正文
目標大略如下:
- 弄個右鍵選單
- 按下時複製路徑到剪貼簿
弄個右鍵選單
再複習一下我之前寫的”Open CMD Here”之後,我發現reg是這樣寫的:
- 資料夾背景/桌面:
HKEY_CLASSES_ROOT\Directory\Background\shell
- 資料夾:
HKEY_CLASSES_ROOT\Directory\shell
- 檔案:
HKEY_CLASSES_ROOT\*\shell
orHKEY_CLASSES_ROOT\[副檔名]\shell
這些是按右鍵的對象,然後如果想要新增一個選項
就在某個shell下新增一個key,假設叫做MyOption ,以資料夾背景對象作範例:
這個key的(Default)值就會是右鍵選單中的名稱:
再來是這個選項的圖標,在剛剛的MyOption裡面新增一個String,名字叫做Icon,值可以是你圖標的路徑或是用imgeres.dll
這裡介紹imgeres.dll
imgeres.dll 就是一個包含各種windows常用圖標的dll檔,這邊有人很好心幫你列出所有圖標:Icons in imageres.dll
用的時候是:imageres.dll,[序號]
,我用207當範例,注意逗號後沒有空格
最後是這個選項要幹嘛,在MyOption下創一個”command”的key,這裡名稱一定是command
他的(Default)值就是要跑的指令,舉例如下:
那當我按下去的時候就會跳出explorer.exe
又或者你可以用自己的程式(路徑中有空格要加雙引號),但是需要絕對路徑,他好像只讀C:\Windows\System32
之類的,可以自己玩玩看
順帶一提,重寫過註冊碼後,不用重啟explorer,直接測試就可以
比較特殊的是檔案、資料夾對象,他會要填參數:
%1
是指第1個參數,多個參數我就不知道怎麼填了
按下時複製路徑到剪貼簿
用C++寫,雖然說python可能比較好用,但效能問題還是算了
Windows中剪貼版的操作大抵如下:
- OpenClipboard
- EmptyClipboard
- SetClipboardData
- CloseClipboard
但是,這裡會用到GlobalAlloc ,這甚麼呢,我也不知道
但是有人幫我解釋了,而且我不想看:关于Clipboard和GlobalAlloc函数的关系
將文字複製到剪貼簿的程式碼長這樣的:
void writeToClipboard(std::wstring str) {
if (!OpenClipboard(NULL)) return;
EmptyClipboard();
size_t size_m = sizeof(wchar_t) * (str.length() + 1);
HGLOBAL hClipboardData = GlobalAlloc(GMEM_DDESHARE, size_m);
if (!hClipboardData) return;
wchar_t* pchData;
pchData = (wchar_t*)GlobalLock(hClipboardData);
if (!pchData) return;
wcscpy_s(pchData, str.length(), str.c_str());
GlobalUnlock(hClipboardData);
SetClipboardData(CF_UNICODETEXT, hClipboardData);
CloseClipboard();
}
所以接下來只要取得資料夾、檔案路徑就好了
全部程式碼:
#include <windows.h>
#include <locale>
#define BUFFER_SIZE 2048
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"wmainCRTStartup\"")
wchar_t path[BUFFER_SIZE];
void writePathToClipboard();
int wmain(int argc, wchar_t* argv[]) {
setlocale(LC_ALL, ".UTF8");
if (argc >= 2) {
size_t size_m = wcslen(argv[1]) + 1;
wcscpy_s(path, size_m, argv[1]);
} else {
GetCurrentDirectory(BUFFER_SIZE, path);
}
writePathToClipboard();
}
void writePathToClipboard() {
if (!OpenClipboard(NULL)) return;
EmptyClipboard();
size_t size_m = sizeof(wchar_t) * (wcslen(path) + 1);
HGLOBAL hClipboardData = GlobalAlloc(GMEM_DDESHARE, size_m);
if (!hClipboardData) return;
wchar_t* pchData;
pchData = (wchar_t*)GlobalLock(hClipboardData);
if (!pchData) return;
wcscpy_s(pchData, size_m / sizeof(wchar_t), path);
GlobalUnlock(hClipboardData);
SetClipboardData(CF_UNICODETEXT, hClipboardData);
CloseClipboard();
}
這是有Unicode支持,在搞定Unicode之前花了我超多時間,因為單純的wchar_t
是沒辦法好好展示Unicode的
所以編譯之後就丟到想要的地方,然後註冊表改一下就好
結果
我寫的註冊表
Windows Registry Editor Version 5.00
; https://medium.com/@Hyno/%E5%8F%B3%E9%8D%B5%E5%8F%96%E5%BE%97%E7%95%B6%E5%89%8D%E6%AA%94%E6%A1%88%E8%B7%AF%E5%BE%91-2fca6fc8e3d0
; by Hyno
[HKEY_CLASSES_ROOT\Directory\shell\path2clip]
@="Get Folder Path"
"Icon"="imageres.dll,241"
[HKEY_CLASSES_ROOT\Directory\shell\path2clip\command]
@="\"C:\\path\\to\\path2clip.exe\" \"%1\""
[HKEY_CLASSES_ROOT\Directory\Background\shell\path2clip]
@="Get Folder Path"
"Icon"="imageres.dll,241"
[HKEY_CLASSES_ROOT\Directory\Background\shell\path2clip\command]
@="\"C:\\path\\to\\path2clip.exe\""
[HKEY_CLASSES_ROOT\*\shell\path2clip]
"Icon"="imageres.dll,241"
@="Get File Path"
[HKEY_CLASSES_ROOT\*\shell\path2clip\command]
@="\"C:\\path\\to\\path2clip.exe\" \"%1\""
看在我這麼好心的份上多給我拍幾次手不過分吧