[Win 32]ShellHookの実現
このブログはCSDNブロガーzuishikonghuanが作成したもので、著作権はzuishikonghuanが所有しています.転載は出典を明記してください.http://blog.csdn.net/zuishikonghuan/article/details/49133099
Windowsを起動し、Win 32サブシステムをロードし、ユーザーセッションにログインすると、Shellプログラムが起動します.デフォルトはexplorerです.exeは、デスクトップやタスクバーなどを見ていますが、実際にはShellはカスタマイズでき、システムの代わりにShellを自分で書くことができます.Windows Shellを記述するコアテクノロジーの一つであるShellHookを見てみましょう.
ShellHookって何?ウィンドウが作成、アクティブ化、クローズされると、explorerは常に対応するメッセージをキャプチャし、タスクバーを更新することができます.ShellHookによって実現されます.
explorerは常に対応するメッセージをキャプチャし、タスクバーを更新することができます.最初は、explorerはtimerタイミングで列挙ウィンドウを呼び出すか、グローバルメッセージフックを使用して実現されると推測していましたが、この2つの方法はシステムリソースの消費が大きく、実際には、この機能を実現するにはShellHookを使用すると便利で安定しており、リソースの占有が大きいという問題はありません.
完全な例のソースコードは次のとおりです(注釈は詳細です).
効果図:
Windowsを起動し、Win 32サブシステムをロードし、ユーザーセッションにログインすると、Shellプログラムが起動します.デフォルトはexplorerです.exeは、デスクトップやタスクバーなどを見ていますが、実際にはShellはカスタマイズでき、システムの代わりにShellを自分で書くことができます.Windows Shellを記述するコアテクノロジーの一つであるShellHookを見てみましょう.
ShellHookって何?ウィンドウが作成、アクティブ化、クローズされると、explorerは常に対応するメッセージをキャプチャし、タスクバーを更新することができます.ShellHookによって実現されます.
explorerは常に対応するメッセージをキャプチャし、タスクバーを更新することができます.最初は、explorerはtimerタイミングで列挙ウィンドウを呼び出すか、グローバルメッセージフックを使用して実現されると推測していましたが、この2つの方法はシステムリソースの消費が大きく、実際には、この機能を実現するにはShellHookを使用すると便利で安定しており、リソースの占有が大きいという問題はありません.
完全な例のソースコードは次のとおりです(注釈は詳細です).
#include <windows.h>
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
//#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
WNDCLASS wc;
const TCHAR* AppName = TEXT("MyWindowClass1");
HWND hwnd1;
HWND edit2 = 0;
// ShellHook
static UINT WM_SHELLHOOKMESSAGE;
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
//
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;//
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;//
wc.hIcon = LoadIcon(hInstance, TEXT("ICON_1"));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);//
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);//
wc.lpszMenuName = NULL;
wc.lpszClassName = AppName;//
//
if (!RegisterClass(&wc))
{
MessageBox(NULL, TEXT(" !"), TEXT(" "), MB_ICONERROR);
return 0;
}
//
int style = WS_OVERLAPPEDWINDOW;
hwnd1 = CreateWindowEx(WS_EX_TOPMOST, AppName, TEXT("ShellHook"), style, 50, 50, 500, 500, 0, NULL, hInstance, 0);
if (hwnd1 == NULL)
{
MessageBox(NULL, TEXT(" !"), TEXT(" "), MB_ICONERROR);
return 0;
}
// 、
ShowWindow(hwnd1, nCmdShow);
UpdateWindow(hwnd1);
//
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void AddEditText(TCHAR* string, HWND hwnd)// edit control
{
int len = GetWindowTextLength(hwnd);// edit control
SendMessage(hwnd, EM_SETSEL, len, len);//
SendMessage(hwnd, EM_REPLACESEL, 0, (LPARAM)string);//
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg){
case WM_CREATE:
// edit control
edit2 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT(""), WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL | ES_AUTOVSCROLL, 5, 5, 400, 450, hwnd, (HMENU)8, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
SendMessage(edit2, WM_SETFONT, (WPARAM)GetStockObject(17), 0);
// ShellHook
WM_SHELLHOOKMESSAGE = RegisterWindowMessage(TEXT("SHELLHOOK"));
if (!RegisterShellHookWindow(hwnd))MessageBox(hwnd, TEXT("shellhook "), TEXT(""), 0);
break;
case WM_DESTROY://
PostQuitMessage(0);// ,
return 0;
break;
default:
break;
}
// ShellHook
HWND hwin;
if (uMsg == WM_SHELLHOOKMESSAGE){
TCHAR tmp[50] = {0};
hwin = (HWND)lParam;//
// Shell
if (wParam == HSHELL_WINDOWACTIVATED || wParam == HSHELL_RUDEAPPACTIVATED){
AddEditText(TEXT("[ ]"), edit2);
goto print;
}
if (wParam == HSHELL_WINDOWDESTROYED){
AddEditText(TEXT("[ ]"), edit2);
goto print;
}
goto end;
print:
// , toolwindow , ,
DWORD style;
style = GetWindowLongPtr(hwin, GWL_EXSTYLE);//
if (style & WS_EX_TOOLWINDOW){//
AddEditText(TEXT("ToolWindow "), edit2);
}
style = GetWindowLongPtr(hwin, GWL_STYLE);
if (style & WS_CHILD){
AddEditText(TEXT("Child "), edit2);
}
_itot((DWORD)hwin, tmp, 10);// TCHAR
AddEditText(tmp, edit2);
AddEditText(TEXT(" - "), edit2);
DWORD len = GetWindowTextLength(hwin);//
len = len * sizeof(TCHAR);//GetWindowTextLength
//
TCHAR* til = (TCHAR*)VirtualAlloc(NULL, len + 2, MEM_COMMIT, PAGE_READWRITE);//TCHAR* til = new TCHAR[len + 1];
RtlZeroMemory(til, len + 2);// :til[len]='\0';
GetWindowText(hwin, til, len/sizeof(TCHAR) + 2);//
AddEditText(til, edit2);
AddEditText(TEXT("\r
"), edit2);//
//
VirtualFree(til, len + 2, MEM_DECOMMIT);//delete[] til;
return 0;
end:
;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);//
}
効果図: