日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Win32 SDK 编写截图小工具

發布時間:2025/3/13 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Win32 SDK 编写截图小工具 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

開發環境為windows xp,vc6

主要方案為,創建一個主窗口,不進行截圖的時候將其隱藏,并在托盤區創建小圖標,截圖時使窗口全屏透明,捕捉鼠標行為截圖保存,再使窗口隱藏。

以下根據主要步驟將核心內容點出:


(1)注冊窗口類時,將背景色定為黑色,以使截圖時有灰暗的效果


ATOM MyRegisterClass(PWNDCLASSEX wcex,HINSTANCE hInstance) {...wcex->hCursor = LoadCursor(NULL, IDC_CROSS);wcex->hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);...return RegisterClassEx(wcex); }

(2)創建窗口時,用到兩個擴展風格,WS_EX_LAYERED,WS_EX_TOOLWINDOW

前者是將窗口透明化必須設置的窗口風格,后者使窗口成為一個工具窗口,不顯示在任務欄中。

HWND hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOOLWINDOW, "MYSCREENSHOT", 0, WS_POPUP,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

(3)注冊兩套熱鍵,用RegisterHotKey

函數原型為:

BOOL RegisterHotKey(HWND hWnd, // handle to windowint id, // hot key identifierUINT fsModifiers, // key-modifier optionsUINT vk // virtual-key code );
RegisterHotKey(hWnd, 1346, MOD_ALT | MOD_CONTROL, 65);RegisterHotKey(hWnd, 1347, MOD_CONTROL, 222);65為A的虛鍵碼,222為' or " 的虛鍵碼,適用于左手與右手。

這樣當按下這兩個組合鍵時,窗口會受到一個??? WM_HOTKEY??? 消息,其中,lParam的低位字顯示了alt或是control鍵是否被按下,高位字為虛鍵碼,那么我們只需要在窗口函數中處理該消息,發送一個命令消息開始截圖:

case WM_HOTKEY:{if(HIWORD(lParam) == 65 || HIWORD(lParam) == 222)SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDM_RUN, 0), 0);}break;


IDM_RUN 是一個開始截圖的命令消息

注意窗口銷毀時注銷熱鍵,在WM_DESTROY中

UnregisterHotKey(hWnd, 1346);UnregisterHotKey(hWnd, 1347);

(4)在不進行截圖時,將窗口最小化到托盤,這里要用到 API函數Shell_NotifyIcon和結構體NOTIFYICONDATA,先來看下NOTIFYICONDATA:

typedef struct _NOTIFYICONDATA { DWORD cbSize; HWND hWnd; UINT uID; UINT uFlags; UINT uCallbackMessage; HICON hIcon; char szTip[64]; } NOTIFYICONDATA, *PNOTIFYICONDATA; 其中,

cbSize : 結構的長度,用“位”來做單位。一般在程序中,我們用(DWORD)sizeof(NOTIFYICONDATA) 給它賦值。
HWnd : 一個句柄,如果對托盤中的圖標進行操作,相應的消息就傳給這個句柄所代表的窗口。自然了,大多數情況下是this->m_hWnd嘍。
uID : 在工程中定義的圖標ID?


uFlags : 這個成員標志著其他哪些成員的數據是有效的,分別為NIF_ICON, NIF_MESSAGE, NIF_TIP,分別代表著數據有效的成員是hIcon, uCallbackMessage, szTip。當然,三個值可以用“|”聯系到一起。下面分別對涉及到的成員進行闡述?


hIcon : 要增加,刪除或修改的圖標句柄。如果只知道個uID, 一般可能會用函數LoadIcon來得到句柄。例如LoadIcon ( AfxGetInstanceHandle() ,MAKEINTRESOURCE (IDR_MAINFRAME) )。

uCallbackMessage : 這在對托盤區的操作中,是比較重要的數據成員。這是個消息標志,當用鼠標對托盤區相應圖標進行操作的時候,就會傳遞消息給Hwnd所代表的窗口。所以說,在uFlags中,一般都得標志它有效。這里一般都是自定義的消息。

szTip : 鼠標移動到托盤圖標上時的提示文字。

我們這里用一個自定義消息來接收托盤圖標的消息:

#define MY_ICON_MESSAGE (WM_USER+1) ... NOTIFYICONDATA g_nid; ... g_nid.uCallbackMessage = MY_ICON_MESSAGE;
那么此時,第三個參數可以隨便填。接下來處理這個消息,其中,wParam接收的是圖標的ID,而lParam接收的是鼠標的行為

case MY_ICON_MESSAGE:{switch(lParam){case WM_RBUTTONDOWN:{HMENU hMenu = CreateMenu();HMENU hPopupMenu = CreateMenu();AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hPopupMenu, 0);AppendMenu(hPopupMenu, MF_STRING, IDM_RUN, "&Run");AppendMenu(hPopupMenu, MF_SEPARATOR, 0, 0);AppendMenu(hPopupMenu, MF_STRING, IDM_QUIT, "&Quit");POINT point;GetCursorPos(&point);SetForegroundWindow(hWnd);TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN, point.x, point.y, 0, hWnd, 0);}break;case WM_LBUTTONDBLCLK:SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDM_RUN, 0), 0);break;}}break;


右鍵單擊時,彈出一個菜單,有兩個選項,運行和退出,當左鍵雙擊時,與運行截圖有相同的作用,發送一個IDM_RUN 的命令消息。注意,TrackPopupMenu之前的SetForegroundWindow是必要的,沒有這一句,則彈出的菜單不會自動消失。


(5)接下去來處理IDM_RUN消息:

case IDM_RUN:{g_nid.hIcon = LoadIcon(g_hInstance, (LPCTSTR)IDI_ON); Shell_NotifyIcon(NIM_MODIFY, &g_nid);hSrcDC = GetDC(GetDesktopWindow());HMODULE hModule = LoadLibrary("User32.dll");lpfnSetLayeredWindowAttributes myfunc = (lpfnSetLayeredWindowAttributes)GetProcAddress(hModule, "SetLayeredWindowAttributes"); FreeLibrary(hModule);ShowWindow(hWnd, SW_MAXIMIZE);myfunc(hWnd, 0, 100, LWA_ALPHA);g_State = TRUE;}break;
首先是一個替換托盤區圖標的操作,顯示截圖正在進行中。

然后先取得桌面DC,(先把全屏給截了,然后再跟蹤鼠標的操作來對這張全屏圖“剪裁”)hSrcDC是一個窗口消息處理函數的靜態局部DC句柄。

接著利用API函數SetLayeredWindowAttributes來設置窗口為透明,其函數原型為:

BOOL SetLayeredWindowAttributes(HWND hwnd, // handle to the layered windowCOLORREF crKey, // specifies the color keyBYTE bAlpha, // value for the blend functionDWORD dwFlags // action );
詳細的解答請參照MSDN

這里需要申明對該函數的指針,注意,LWA_ALPHA需要自行定義

typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD); ... #define LWA_ALPHA 0x00000002
g_State 是一個全局變量,用以記錄是否在截圖狀態,在鼠標的消息處理函數中會對此變量進行判斷,是的話再進行相應的操作。


(6)接下去跟蹤鼠標的行為“剪裁”剛才的桌面DC,先找到需要的矩形塊坐標。

主要過程為:

1.在WM_LBUTTONDOWN中記錄第一個點,將它保存在靜態POINT變量中;

2.在WM_MOUSEMOVE中在透明窗口上實時刷新并畫線以顯示截圖的區域;

3.在WM_LBUTTONUP中記錄第二個點,從而取得需要剪裁的區域矩形,用BitBlt復制DC內容,并保存位圖文件。最后使窗口隱藏起來,更換托盤區圖標等初始化工作。


具體代碼在此不再羅嗦了,詳見源碼。


成品exe及源代碼:點擊打開鏈接


轉載于:https://www.cnblogs.com/silyvin/archive/2012/05/07/9106906.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的Win32 SDK 编写截图小工具的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。