今天整理文件,看到這個大二時,剛學習windows程序設計時寫的一個魔獸顯血工具.取名NoCheating,是想說明本身不是做弊工具,僅僅顯示血條而已.c++
vs2019打開,升級,編譯,竟然還能編譯運行windows
那個時候剛開始玩魔獸爭霸3下面的真三國無雙,當時魔獸的版本還不能自動顯示人物血條,須要按下[鍵顯示己方血條,或者]鍵顯示敵方血條,或者alt鍵顯示雙方血條.因此每次打架在補兵的時候,就頗有節奏的按着alt鍵,按一下,補一下兵,按一下補一下兵(後來,魔獸升級後有了自動顯示血條功能後,不用按alt鍵了,反而不習慣了).因而就想着寫一個工具,自動顯示血條.
原理很簡單,就是模擬用戶按下[,]兩個鍵.
具體的實現用到了當時學的windows程序設計的內容.從新看看這個內容,還能重溫一下windows程序設計的基本步驟和框架.app
首先是windows程序設計的入口函數WinMain.
其參數包括hInstance當前實例句柄,和hPrevInstance(通常爲空),和命令行參數,以及窗口顯示方式.框架
其次就是典型的windows程序設計步驟.
設計一個窗口類: 即定義WNDCLASS對象,並設置參數.
註冊窗口對象: RegisterClass.
建立窗口對象: CreateWindow.
顯示窗口:ShowWindow.
更新窗口: UpdateWindow.
而後最重要的,消息循環:函數
while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
接着在WndProc回調函數中處理windows消息:
窗口建立消息中建立2個timer
在timer1消息中經過FindWindow找到魔獸窗口句柄.
在timer2消息中向魔獸窗口發送[]按鍵消息.
窗口銷燬消息中關閉timer,關閉魔獸窗口句柄,發送退出程序消息.工具
#include<windows.h> #include<tlhelp32.h> #include<TCHAR.h> #define IDT_TIMER1 1 #define IDT_TIMER2 2 LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { static TCHAR szAppName[]=TEXT("NoCheating"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hInstance = hInstance; wndclass.lpfnWndProc = WndProc; wndclass.lpszClassName = szAppName; wndclass.lpszMenuName = NULL; wndclass.style = CS_HREDRAW | CS_VREDRAW; if(!RegisterClass(&wndclass)) { MessageBox(NULL,TEXT("This application need windows NT!"), szAppName,MB_ICONERROR); return 0; } hwnd = CreateWindow( szAppName, TEXT("不做弊"), WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME, GetSystemMetrics(SM_CXSCREEN) / 2 - 100, GetSystemMetrics(SM_CYSCREEN) / 2 - 50, 200, 100, NULL, NULL, hInstance, NULL ); ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { static HANDLE hWar; static BOOL bGetID; switch(message) { case WM_CREATE: SetTimer(hwnd,IDT_TIMER1,10000,NULL); SetTimer(hwnd,IDT_TIMER2,10000,NULL); return 0; case WM_TIMER: switch(wParam) { case IDT_TIMER1: hWar = FindWindow(NULL,"Warcraft III"); bGetID = hWar ? TRUE : FALSE; break; case IDT_TIMER2: if(bGetID) { SendMessage(hWar,WM_KEYDOWN,0xDB,0); SendMessage(hWar,WM_KEYDOWN,0xDD,0); } break; } return 0; case WM_DESTROY: KillTimer(hwnd,IDT_TIMER2); CloseHandle(hWar); PostQuitMessage(0); return 0; default: return DefWindowProc(hwnd,message,wParam,lParam); } }
許久不寫windows程序,看完,彷彿又回到了大學時代.學習