以下是一些封装的Win32 API类;备用;
#pragma once
#include
class XqWindow
{
public:
XqWindow(HINSTANCE hInst);
~XqWindow();
private:
HWND hWnd; // 对外只读,确保安全
HINSTANCE hInstance;
public:
// 返回窗口对象句柄
HWND GetHandle();
// 消息处理。需要后续默认处理则需要返回0;停止该消息后续处理,则返回1
virtual int HandleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
private:
// 原始窗口过程
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
private:
// 已注册过的类集合
static std::vector registeredClassArray;
public:
// 创建窗口
void Create();
};
#include "stdafx.h"
#include "XqWindow.h"
std::vector XqWindow::registeredClassArray;
// 创建窗口
void XqWindow::Create()
{
wchar_t szClassName[32];
wchar_t szTitle[128];
void* _vPtr = *((void**)this);
::wsprintf(szClassName, L"%p", _vPtr);
std::vector::iterator it;
for (it = registeredClassArray.begin(); it != registeredClassArray.end(); it++) // 判断对象的类是否注册过
{
if ((*it) == _vPtr)
break;
}
if (it == registeredClassArray.end()) // 如果没注册过,则进行注册
{
//注册窗口类
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = XqWindow::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = this->hInstance;
wcex.hIcon = NULL;
wcex.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szClassName;
wcex.hIconSm = NULL;
if (0 != ::RegisterClassEx(&wcex)) // 把注册成功的类加入链表
{
registeredClassArray.push_back(_vPtr);
}
}
// 创建窗口
if (this->hWnd == NULL)
{
::wsprintf(szTitle, L"窗口类名(C++类虚表指针):%p", _vPtr);
HWND hwnd = ::CreateWindow(szClassName,
szTitle,
WS_OVERLAPPEDWINDOW,
0, 0, 800, 600,
NULL,
NULL,
hInstance,
(LPVOID)this
);
if (hwnd == NULL)
{
this->hWnd = NULL;
wchar_t msg[100];
::wsprintf(msg, L"CreateWindow()失败:%ld", ::GetLastError());
::MessageBox(NULL, msg, L"错误", MB_OK);
return;
}
}
}
XqWindow::XqWindow(HINSTANCE hInst)
{
this->hWnd = NULL;
this->hInstance = hInst;
}
XqWindow::~XqWindow()
{
if ( this->hWnd!=NULL && ::IsWindow(this->hWnd) ) // C++对象被销毁之前,销毁窗口对象
{
::DestroyWindow(this->hWnd); // Tell system to destroy hWnd and Send WM_DESTROY to wndproc
}
}
HWND XqWindow::GetHandle()
{
return this->hWnd;
}
// 消息处理。需要后续默认处理则需要返回0;停止该消息后续处理,则返回1
int XqWindow::HandleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return 0;
}
// 原始窗口过程
LRESULT CALLBACK XqWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
XqWindow* pObj = NULL;
if (message == WM_CREATE) // 在此消息收到时,把窗口对象句柄赋给C++对象成员,同时把C++对象地址赋给窗口对象成员
{
pObj = (XqWindow*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
pObj->hWnd = hWnd; // 在此处获取HWND,此时CreateWindow()尚未返回。
::SetWindowLong(hWnd, GWL_USERDATA, (LONG)pObj); // 通过USERDATA把HWND和C++对象关联起来
}
pObj = (XqWindow*)::GetWindowLong(hWnd, GWL_USERDATA);
switch (message)
{
case WM_CREATE:
pObj->HandleMessage(hWnd, message, wParam, lParam);
break;
case WM_DESTROY:
if (pObj != NULL) // 此时,窗口对象已经销毁,通过设置hWnd=NULL,来通知C++对象
{
pObj->hWnd = NULL;
}
break;
default:
pObj = (XqWindow*)::GetWindowLong(hWnd, GWL_USERDATA);
if (pObj != NULL)
{
if (pObj->HandleMessage(hWnd, message, wParam, lParam) == 0) // 调用子类的消息处理虚函数
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
else
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
}
return 0;
}
TestWindow.cpp
#pragma once
#include "XqWindow.h"
class TestWindow :
public XqWindow
{
public:
TestWindow(HINSTANCE);
~TestWindow();
protected:
int HandleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
private:
// 业务数据部分
int rectWidth;
int rectHeight;
};
#include "stdafx.h"
#include "TestWindow.h"
TestWindow::TestWindow(HINSTANCE hInst) :XqWindow(hInst)
{
rectWidth = 300;
rectHeight = 200;
}
TestWindow::~TestWindow()
{
}
int TestWindow::HandleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
hdc = ::BeginPaint(hWnd, &ps);
::Rectangle(hdc, 0, 0, this->rectWidth, this->rectHeight);
::EndPaint(hWnd, &ps);
return 1;
default:
break;
}
return 0;
}
pTest = new TestWindow(theApp.m_hInstance);
pTest->Create();
::ShowWindow(pTest->GetHandle(), SW_SHOW);
::UpdateWindow(pTest->GetHandle());
========
#include
#include "LogWriter.h"
#include "WindowsMessages.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t* szCmdLine, int iCmdShow)
{
LOG(L"程序开始");
wchar_t szClassName[] = L"MyWindowClass";
// 注册窗口类
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szClassName;
wcex.hIconSm = NULL;
LOG(L"RegisterClassEx()开始");
::RegisterClassEx(&wcex);
LOG(L"RegisterClassEx()返回");
// 创建窗口
LOG(L"CreateWindow()开始");
HWND hWnd = CreateWindow(szClassName, L"Windows 消息测试", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
LOG(L"CreateWindow()返回");
LOG(L"ShowWindow()开始");
::ShowWindow(hWnd, SW_SHOW);
LOG(L"ShowWindow()返回");
LOG(L"UpdateWindow()开始");
::UpdateWindow(hWnd);
LOG(L"UpdateWindow()返回");
// 开启消息循环, 直到取回WM_QUIT消息,GetMessage()返回0,退出循环
MSG msg;
BOOL bRet = 0;
wchar_t str[256];
while (1)
{
LOG(L"GetMessage()开始");
bRet = GetMessage(&msg, NULL, 0, 0);
::wsprintf(str, L"GetMessage()返回,取回消息:%s,对应窗口:%X", get_msg_name(msg.message), msg.hwnd);
LOG(str);
if (bRet == 0)
{
// 收到了WM_QUIT,退出循环
break;
}
else if (bRet == -1)
{
// 处理错误
}
else
{
TranslateMessage(&msg);
LOG(L"DispatchMessage()开始");
DispatchMessage(&msg); // 根据msg.hwnd调用指定窗口过程
LOG(L"DispatchMessage()返回");
}
}
// 程序结束
LOG(L"程序结束");
ENDLOG
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
wchar_t str[128];
::wsprintf(str, L"WndProc被调用开始,消息参数: %s", get_msg_name(message));
LOG(str);
int r = 0;
switch (message)
{
case WM_CREATE:
break;
case WM_DESTROY:
::PostQuitMessage(0); // 窗口销毁后,指示退出消息循环
break;
default:
LOG(L"DefWindowProc()开始");
r = ::DefWindowProc(hWnd, message, wParam, lParam);
LOG(L"DefWindowProc()返回");
LOG(L"WndProc返回");
return r;
}
LOG(L"WndProc返回");
return 0;
}
LogWriter.cpp
#pragma once
/*
日志记录类
功能描述:
根据当前时间自动生成日志文件名,自动记录日志到日志文件。
日志文件名格式(样例):
20141219211252255.log
日志内容格式(样例):
2014年12月19日11时52分55秒,源文件:e:\work\udptest\udptestdlg.cpp,第109行, 这里是要写的日志内容
使用方式:
此类采用单例模式设计,为使用方便,定义了两个宏供用户调用。样例代码:
LOG(L"这里是要写的日志内容"); // 记录日志到文件
ENDLOG // 程序退出之前调用,关闭日志文件
*/
#include
class LogWriter
{
protected:
LogWriter();
~LogWriter();
private:
wchar_t fileName[1024];
FILE* fp;
public:
void Log(wchar_t* log);
public:
static LogWriter* GetLogWriter();
static void DeleteLogWriter();
private:
static LogWriter* theOnlyLogWriter;
};
#define LOG(x) \
{ \
wchar_t buffer[2048]; \
SYSTEMTIME st; \
::GetLocalTime(&st); \
swprintf_s(buffer, L"%04d年%02d月%02d日%02d时%02d分%02d秒,源文件:%s,第%d行, %s\n", \
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, \
TEXT(__FILE__), __LINE__, x); \
LogWriter::GetLogWriter()->Log(buffer); \
}
#define ENDLOG \
LogWriter::DeleteLogWriter();
#include
#include "LogWriter.h"
#include "share.h"
#include
LogWriter* LogWriter::theOnlyLogWriter = NULL;
LogWriter::LogWriter()
{
// determine the log file's name, yyyyMMddhhmmss.log
SYSTEMTIME st;
::GetLocalTime(&st);
::swprintf_s(this->fileName, L"%04d%02d%02d%02d%02d%02d.log", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
fp = ::_wfsopen(this->fileName, L"w,ccs=UTF-8", _SH_DENYNO); // 以共享读写模式打开日志文件
}
// 线程安全的写入文件
void LogWriter::Log(wchar_t* log)
{
if (fp != NULL)
{
::fwprintf(this->fp, L"%s", log);
}
}
LogWriter::~LogWriter()
{
if (this->fp != NULL)
::fclose(fp);
}
LogWriter* LogWriter::GetLogWriter()
{
if (theOnlyLogWriter == NULL)
{
theOnlyLogWriter = new LogWriter();
}
return theOnlyLogWriter;
}
void LogWriter::DeleteLogWriter()
{
if (theOnlyLogWriter != NULL)
{
delete theOnlyLogWriter;
theOnlyLogWriter = NULL;
}
}
#pragma once
#include
wchar_t* get_msg_name(int message);
static wchar_t* Messages[] =
{
L"WM_NULL",//0x0000
L"WM_CREATE",//0x0001
L"WM_DESTROY",//0x0002
L"WM_MOVE",//0x0003
L"WM_SIZEWAIT",//0x0004
L"WM_SIZE",//0x0005
L"WM_ACTIVATE",//0x0006
L"WM_SETFOCUS",//0x0007
L"WM_KILLFOCUS",//0x0008
L"WM_SETVISIBLE",//0x0009
L"WM_ENABLE",//0x000a
L"WM_SETREDRAW",//0x000b
L"WM_SETTEXT",//0x000c
L"WM_GETTEXT",//0x000d
L"WM_GETTEXTLENGTH",//0x000e
L"WM_PAINT",//0x000f
L"WM_CLOSE", /* 0x10 */
L"WM_QUERYENDSESSION",//0x0011
L"WM_QUIT",//0x0012
L"WM_QUERYOPEN",//0x0013
L"WM_ERASEBKGND",//0x0014
L"WM_SYSCOLORCHANGE",//0x0015
L"WM_ENDSESSION",//0x0016
L"WM_SYSTEMERROR",//0x0017
L"WM_SHOWWINDOW",//0x0018
L"WM_CTLCOLOR",//0x0019
L"WM_WININICHANGE",//0x001a
L"WM_DEVMODECHANGE",//0x001b
L"WM_ACTIVATEAPP",//0x001c
L"WM_FONTCHANGE",//0x001d
L"WM_TIMECHANGE",//0x001e
L"WM_CANCELMODE",//0x001f
L"WM_SETCURSOR", /* 0x20 */
L"WM_MOUSEACTIVATE",//0x0021
L"WM_CHILDACTIVATE",//0x0022
L"WM_QUEUESYNC",//0x0023
L"WM_GETMINMAXINFO",//0x0024
L"WM_LOGOFF",//0x0025
L"WM_PAINTICON",//0x0026
L"WM_ICONERASEBKGND",//0x0027
L"WM_NEXTDLGCTL",//0x0028
L"WM_ALTTABACTIVE",//0x0029
L"WM_SPOOLERSTATUS",//0x002a
L"WM_DRAWITEM",//0x002b
L"WM_MEASUREITEM",//0x002c
L"WM_DELETEITEM",//0x002d
L"WM_VKEYTOITEM",//0x002e
L"WM_CHARTOITEM",//0x002f
L"WM_SETFONT", /* 0x30 */
L"WM_GETFONT",//0x0031
L"WM_SETHOTKEY",//0x0032
L"WM_GETHOTKEY",//0x0033
L"WM_FILESYSCHANGE",//0x0034
L"WM_ISACTIVEICON",//0x0035
L"WM_QUERYPARKICON",//0x0036
L"WM_QUERYDRAGICON",//0x0037
L"WM_WINHELP",//0x0038
L"WM_COMPAREITEM",//0x0039
L"WM_FULLSCREEN",//0x003a
L"WM_CLIENTSHUTDOWN",//0x003b
L"WM_DDEMLEVENT",//0x003c
L"WM_GETOBJECT",//0x003d
NULL,//0x003e
L"WM_CALCSCROLL",//0x003f
L"WM_TESTING", /* 0x40 */
L"WM_COMPACTING",//0x0041
L"WM_OTHERWINDOWCREATED",//0x0042
L"WM_OTHERWINDOWDESTROYED",//0x0043
L"WM_COMMNOTIFY",//0x0044
L"WM_MEDIASTATUSCHANGE",//0x0045
L"WM_WINDOWPOSCHANGING", /* 0x0046 */
L"WM_WINDOWPOSCHANGED", /* 0x0047 */
L"WM_POWER",//0x0048
L"WM_COPYGLOBALDATA",//0x0049
L"WM_COPYDATA",//0x004a
L"WM_CANCELJOURNAL",//0x004b
L"WM_LOGONNOTIFY",//0x004c
L"WM_KEYF1",//0x004d
L"WM_NOTIFY",//0x004e
L"WM_ACCESS_WINDOW",//0x004f
L"WM_INPUTLANGCHANGEREQUEST",/* 0x0050 */
L"WM_INPUTLANGCHANGE",//0x0051
L"WM_TCARD",//0x0052
L"WM_HELP",//0x0053
L"WM_USERCHANGED",//0x0054
L"WM_NOTIFYFORMAT",//0x0055
NULL,//0x0056
NULL,//0x0057
NULL,//0x0058
NULL,//0x0059
NULL,//0x005a
NULL,//0x005b
NULL,//0x005c
NULL,//0x005d
NULL,//0x005e
NULL,//0x005f
NULL,/* 0x0060 */
NULL,//0x0061
NULL,//0x0062
NULL,//0x0063
NULL,//0x0064
NULL,//0x0065
NULL,//0x0066
NULL,//0x0067
NULL,//0x0068
NULL,//0x0069
NULL,//0x006a
NULL,//0x006b
NULL,//0x006c
NULL,//0x006d
NULL,//0x006e
NULL,//0x006f
L"WM_FINALDESTROY",/* 0x0070 */
L"WM_MEASUREITEM_CLIENTDATA",//0x0071
L"WM_TASKACTIVATED",//0x0072
L"WM_TASKDEACTIVATED",//0x0073
L"WM_TASKCREATED",//0x0074
L"WM_TASKDESTROYED",//0x0075
L"WM_TASKUICHANGED",//0x0076
L"WM_TASKVISIBLE",//0x0077
L"WM_TASKNOTVISIBLE",//0x0078
L"WM_SETCURSORINFO",//0x0079
NULL,//0x007a
L"WM_CONTEXTMENU",//0x007b
L"WM_STYLECHANGING",//0x007c
L"WM_STYLECHANGED",//0x007d
L"WM_DISPLAYCHANGE",//0x007e
L"WM_GETICON",//0x007f
L"WM_SETICON", /* 0x0080 */
L"WM_NCCREATE", /* 0x0081 */
L"WM_NCDESTROY", /* 0x0082 */
L"WM_NCCALCSIZE", /* 0x0083 */
L"WM_NCHITTEST", /* 0x0084 */
L"WM_NCPAINT", /* 0x0085 */
L"WM_NCACTIVATE", /* 0x0086 */
L"WM_GETDLGCODE", /* 0x0087 */
L"WM_SYNCPAINT",//0x0088
L"WM_SYNCTASK",//0x0089
NULL,//0x008a
L"WM_KLUDGEMINRECT",//0x008b
L"WM_LPKDRAWSWITCHWND",//0x008c
NULL,//0x008d
NULL,//0x008e
NULL,//0x008f
NULL,/* 0x0090 */
NULL,//0x0091
NULL,//0x0092
NULL,//0x0093
NULL,//0x0094
NULL,//0x0095
NULL,//0x0096
NULL,//0x0097
NULL,//0x0098
NULL,//0x0099
NULL,//0x009a
NULL,//0x009b
NULL,//0x009c
NULL,//0x009d
NULL,//0x009e
NULL,//0x009f
L"WM_NCMOUSEMOVE", /* 0x00A0 *//* 0x00A0 */
L"WM_NCLBUTTONDOWN", /* 0x00A1 */
L"WM_NCLBUTTONUP", /* 0x00A2 */
L"WM_NCLBUTTONDBLCLK", /* 0x00A3 */
L"WM_NCRBUTTONDOWN", /* 0x00A4 */
L"WM_NCRBUTTONUP", /* 0x00A5 */
L"WM_NCRBUTTONDBLCLK", /* 0x00A6 */
L"WM_NCMBUTTONDOWN", /* 0x00A7 */
L"WM_NCMBUTTONUP", /* 0x00A8 */
L"WM_NCMBUTTONDBLCLK", /* 0x00A9 */
NULL,//0x00AA
L"WM_NCXBUTTONDOWN",//0x00AB
L"WM_NCXBUTTONUP",//0x00AC
L"WM_NCXBUTTONDBLCLK",//0x00AD
L"WM_NCUAHDRAWCAPTION", /* 0x00AE */
L"WM_NCUAHDRAWFRAME", /* 0x00AF */
L"EM_GETSEL32", /* 0x00b0 */ /* 0x00B0 - Win32
Edit controls */
L"EM_SETSEL32", /* 0x00b1 */
L"EM_GETRECT32", /* 0x00b2 */
L"EM_SETRECT32", /* 0x00b3 */
L"EM_SETRECTNP32", /* 0x00b4 */
L"EM_SCROLL32", /* 0x00b5 */
L"EM_LINESCROLL32", /* 0x00b6 */
L"EM_SCROLLCARET32", /* 0x00b7 */
L"EM_GETMODIFY32", /* 0x00b8 */
L"EM_SETMODIFY32", /* 0x00b9 */
L"EM_GETLINECOUNT32", /* 0x00ba */
L"EM_LINEINDEX32", /* 0x00bb */
L"EM_SETHANDLE32", /* 0x00bc */
L"EM_GETHANDLE32", /* 0x00bd */
L"EM_GETTHUMB32", /* 0x00be */
NULL, /* 0x00bf */
NULL, /* 0x00c0 */
L"EM_LINELENGTH32", /* 0x00c1 */
L"EM_REPLACESEL32", /* 0x00c2 */
L"EM_SETFONT", /* 0x00c3 */
L"EM_GETLINE32", /* 0x00c4 */
L"EM_LIMITTEXT32", /* 0x00c5 */
L"EM_CANUNDO32", /* 0x00c6 */
L"EM_UNDO32", /* 0x00c7 */
L"EM_FMTLINES32", /* 0x00c8 */
L"EM_LINEFROMCHAR32", /* 0x00c9 */
L"EM_SETWORDBREAK", /* 0x00ca */
L"EM_SETTABSTOPS32", /* 0x00cb */
L"EM_SETPASSWORDCHAR32", /* 0x00cc */
L"EM_EMPTYUNDOBUFFER32", /* 0x00cd */
L"EM_GETFIRSTVISIBLELINE32", /* 0x00ce */
L"EM_SETREADONLY32", /* 0x00cf */
L"EM_SETWORDBREAKPROC32", /* 0x00d0 */
L"EM_GETWORDBREAKPROC32", /* 0x00d1 */
L"EM_GETPASSWORDCHAR32", /* 0x00d2 */
L"EM_SETMARGINS32", /* 0x00d3 */
L"EM_GETMARGINS32", /* 0x00d4 */
L"EM_GETLIMITTEXT32", /* 0x00d5 */
L"EM_POSFROMCHAR32", /* 0x00d6 */
L"EM_CHARFROMPOS32", /* 0x00d7 */
L"EM_SETIMESTATUS",//0x00D8
L"EM_GETIMESTATUS",//0x00D9
L"EM_MSGMAX",//0x00DA
NULL,//0x00DB
NULL,//0x00DC
NULL,//0x00DD
NULL,//0x00DE
NULL,//0x00DF
L"SBM_SETPOS32", /* 0x00e0 *//* 0x00E0 - Win32
Scrollbars */
L"SBM_GETPOS32", /* 0x00e1 */
L"SBM_SETRANGE32", /* 0x00e2 */
L"SBM_GETRANGE32", /* 0x00e3 */
L"SBM_ENABLE_ARROWS32", /* 0x00e4 */
NULL,//0x00e5
L"SBM_SETRANGEREDRAW32", /* 0x00e6 */
NULL,//0x00e7
NULL,//0x00e8
L"SBM_SETSCROLLINFO32", /* 0x00e9 */
L"SBM_GETSCROLLINFO32", /* 0x00ea */
NULL,//0x00eb
NULL,//0x00ec
NULL,//0x00ed
NULL,//0x00ee
NULL,//0x00ef
L"BM_GETCHECK32", /* 0x00f0 *//* 0x00F0 - Win32
Buttons */
L"BM_SETCHECK32", /* 0x00f1 */
L"BM_GETSTATE32", /* 0x00f2 */
L"BM_SETSTATE32", /* 0x00f3 */
L"BM_SETSTYLE32", /* 0x00f4 */
L"BM_CLICK32", /* 0x00f5 */
L"BM_GETIMAGE32", /* 0x00f6 */
L"BM_SETIMAGE32", /* 0x00f7 */
NULL,//0x00f8
NULL,//0x00f9
NULL,//0x00fa
NULL,//0x00fb
NULL,//0x00fc
NULL,//0x00fd
NULL,//0x00fe
L"WM_INPUT",//0x00ff
L"WM_KEYDOWN", /* 0x0100 */
L"WM_KEYUP", /* 0x0101 */
L"WM_CHAR", /* 0x0102 */
L"WM_DEADCHAR", /* 0x0103 */
L"WM_SYSKEYDOWN", /* 0x0104 */
L"WM_SYSKEYUP", /* 0x0105 */
L"WM_SYSCHAR", /* 0x0106 */
L"WM_SYSDEADCHAR", /* 0x0107 */
L"WM_YOMICHAR", /* 0x0108 */
L"WM_UNICHAR",//0x0109
L"WM_CONVERTREQUEST",//0x010a
L"WM_CONVERTRESULT",//0x010b
L"WM_INTERIM",//0x010c
L"WM_IME_STARTCOMPOSITION",//0x010d
L"WM_IME_ENDCOMPOSITION",//0x010e
L"WM_IME_COMPOSITION",//0x010f
L"WM_INITDIALOG", /* 0x0110 */
L"WM_COMMAND", /* 0x0111 */
L"WM_SYSCOMMAND", /* 0x0112 */
L"WM_TIMER", /* 0x0113 */
L"WM_HSCROLL", /* 0x0114 */
L"WM_VSCROLL", /* 0x0115 */
L"WM_INITMENU", /* 0x0116 */
L"WM_INITMENUPOPUP", /* 0x0117 */
L"WM_SYSTIMER", /* 0x0118 */
NULL,//0x0119
NULL,//0x011a
NULL,//0x011b
NULL,//0x011c
NULL,//0x011d
NULL,//0x011e
L"WM_MENUSELECT", /* 0x011f */
L"WM_MENUCHAR", /* 0x0120 */
L"WM_ENTERIDLE", /* 0x0121 */
L"WM_MENURBUTTONUP",//0x0122
L"WM_MENUDRAG",//0x0123
L"WM_MENUGETOBJECT",//0x0124
L"WM_UNINITMENUPOPUP",//0x0125
L"WM_MENUCOMMAND",//0x0126
L"WM_CHANGEUISTATE",//0x0127
L"WM_UPDATEUISTATE",//0x0128
L"WM_QUERYUISTATE",//0x0129
NULL,//0x012a
NULL,//0x012b
NULL,//0x012c
NULL,//0x012d
NULL,//0x012e
NULL,//0x012f
NULL,/* 0x0130 */
L"WM_LBTRACKPOINT", /* 0x0131 */
L"WM_CTLCOLORMSGBOX", /* 0x0132 */
L"WM_CTLCOLOREDIT", /* 0x0133 */
L"WM_CTLCOLORLISTBOX", /* 0x0134 */
L"WM_CTLCOLORBTN", /* 0x0135 */
L"WM_CTLCOLORDLG", /* 0x0136 */
L"WM_CTLCOLORSCROLLBAR", /* 0x0137 */
L"WM_CTLCOLORSTATIC", /* 0x0138 */
NULL,//0x0139
NULL,//0x013a
NULL,//0x013b
NULL,//0x013c
NULL,//0x013d
NULL,//0x013e
NULL,//0x013f
L"CB_GETEDITSEL32", /* 0x0140 *//* 0x0140 - Win32
Comboboxes */
L"CB_LIMITTEXT32", /* 0x0141 */
L"CB_SETEDITSEL32", /* 0x0142 */
L"CB_ADDSTRING32", /* 0x0143 */
L"CB_DELETESTRING32", /* 0x0144 */
L"CB_DIR32", /* 0x0145 */
L"CB_GETCOUNT32", /* 0x0146 */
L"CB_GETCURSEL32", /* 0x0147 */
L"CB_GETLBTEXT32", /* 0x0148 */
L"CB_GETLBTEXTLEN32", /* 0x0149 */
L"CB_INSERTSTRING32", /* 0x014a */
L"CB_RESETCONTENT32", /* 0x014b */
L"CB_FINDSTRING32", /* 0x014c */
L"CB_SELECTSTRING32", /* 0x014d */
L"CB_SETCURSEL32", /* 0x014e */
L"CB_SHOWDROPDOWN32", /* 0x014f */
L"CB_GETITEMDATA32", /* 0x0150 */
L"CB_SETITEMDATA32", /* 0x0151 */
L"CB_GETDROPPEDCONTROLRECT32",/* 0x0152 */
L"CB_SETITEMHEIGHT32", /* 0x0153 */
L"CB_GETITEMHEIGHT32", /* 0x0154 */
L"CB_SETEXTENDEDUI32", /* 0x0155 */
L"CB_GETEXTENDEDUI32", /* 0x0156 */
L"CB_GETDROPPEDSTATE32", /* 0x0157 */
L"CB_FINDSTRINGEXACT32", /* 0x0158 */
L"CB_SETLOCALE32", /* 0x0159 */
L"CB_GETLOCALE32", /* 0x015a */
L"CB_GETTOPINDEX32", /* 0x015b */
L"CB_SETTOPINDEX32", /* 0x015c */
L"CB_GETHORIZONTALEXTENT32", /* 0x015d */
L"CB_SETHORIZONTALEXTENT32", /* 0x015e */
L"CB_GETDROPPEDWIDTH32", /* 0x015f */
L"CB_SETDROPPEDWIDTH32", /* 0x0160 */
L"CB_INITSTORAGE32", /* 0x0161 */
NULL,//0x0162
L"CB_MULTIPLEADDSTRING",//0x0163
L"CB_GETCOMBOBOXINFO",//0x0164
NULL,//0x0165
NULL,//0x0166
NULL,//0x0167
NULL,//0x0168
NULL,//0x0169
NULL,//0x016a
NULL,//0x016b
NULL,//0x016c
NULL,//0x016d
NULL,//0x016e
NULL,//0x016f
L"STM_SETICON32", /* 0x0170 */ /* 0x0170 - Win32 Static
controls */
L"STM_GETICON32", /* 0x0171 */
L"STM_SETIMAGE32", /* 0x0172 */
L"STM_GETIMAGE32", /* 0x0173 */
L"STM_MSGMAX",//0x0174
NULL,//0x0175
NULL,//0x0176
NULL,//0x0177
NULL,//0x0178
NULL,//0x0179
NULL,//0x017a
NULL,//0x017b
NULL,//0x017c
NULL,//0x017d
NULL,//0x017e
NULL,//0x017f
L"LB_ADDSTRING32", /* 0x0180 *//* 0x0180 - Win32
Listboxes */
L"LB_INSERTSTRING32", /* 0x0181 */
L"LB_DELETESTRING32", /* 0x0182 */
L"LB_SELITEMRANGEEX32", /* 0x0183 */
L"LB_RESETCONTENT32", /* 0x0184 */
L"LB_SETSEL32", /* 0x0185 */
L"LB_SETCURSEL32", /* 0x0186 */
L"LB_GETSEL32", /* 0x0187 */
L"LB_GETCURSEL32", /* 0x0188 */
L"LB_GETTEXT32", /* 0x0189 */
L"LB_GETTEXTLEN32", /* 0x018a */
L"LB_GETCOUNT32", /* 0x018b */
L"LB_SELECTSTRING32", /* 0x018c */
L"LB_DIR32", /* 0x018d */
L"LB_GETTOPINDEX32", /* 0x018e */
L"LB_FINDSTRING32", /* 0x018f */
L"LB_GETSELCOUNT32", /* 0x0190 */
L"LB_GETSELITEMS32", /* 0x0191 */
L"LB_SETTABSTOPS32", /* 0x0192 */
L"LB_GETHORIZONTALEXTENT32", /* 0x0193 */
L"LB_SETHORIZONTALEXTENT32", /* 0x0194 */
L"LB_SETCOLUMNWIDTH32", /* 0x0195 */
L"LB_ADDFILE32", /* 0x0196 */
L"LB_SETTOPINDEX32", /* 0x0197 */
L"LB_GETITEMRECT32", /* 0x0198 */
L"LB_GETITEMDATA32", /* 0x0199 */
L"LB_SETITEMDATA32", /* 0x019a */
L"LB_SELITEMRANGE32", /* 0x019b */
L"LB_SETANCHORINDEX32", /* 0x019c */
L"LB_GETANCHORINDEX32", /* 0x019d */
L"LB_SETCARETINDEX32", /* 0x019e */
L"LB_GETCARETINDEX32", /* 0x019f */
L"LB_SETITEMHEIGHT32", /* 0x01a0 */
L"LB_GETITEMHEIGHT32", /* 0x01a1 */
L"LB_FINDSTRINGEXACT32", /* 0x01a2 */
L"LB_CARETON32", /* 0x01a3 */
L"LB_CARETOFF32", /* 0x01a4 */
L"LB_SETLOCALE32", /* 0x01a5 */
L"LB_GETLOCALE32", /* 0x01a6 */
L"LB_SETCOUNT32", /* 0x01a7 */
L"LB_INITSTORAGE32", /* 0x01a8 */
L"LB_ITEMFROMPOINT32", /* 0x01a9 */
L"LB_INSERTSTRINGUPPER",//0x01aa
L"LB_INSERTSTRINGLOWER",//0x01ab
L"LB_ADDSTRINGUPPER",//0x01ac
L"LB_ADDSTRINGLOWER",//0x01ad
L"LBCB_STARTTRACK",//0x01ae
L"LBCB_ENDTRACK",//0x01af
NULL,/* 0x01B0 */
L"LB_MULTIPLEADDSTRING",//0x01b1
L"LB_GETLISTBOXINFO",//0x01b2
NULL,//0x01b3
NULL,//0x01b4
NULL,//0x01b5
NULL,//0x01b6
NULL,//0x01b7
NULL,//0x01b8
NULL,//0x01b9
NULL,//0x01ba
NULL,//0x01bb
NULL,//0x01bc
NULL,//0x01bd
NULL,//0x01be
NULL,//0x01bf
NULL,/* 0x01C0 */
NULL,//0x01c1
NULL,//0x01c2
NULL,//0x01c3
NULL,//0x01c4
NULL,//0x01c5
NULL,//0x01c6
NULL,//0x01c7
NULL,//0x01c8
NULL,//0x01c9
NULL,//0x01ca
NULL,//0x01cb
NULL,//0x01cc
NULL,//0x01cd
NULL,//0x01ce
NULL,//0x01cf
NULL,/* 0x01D0 */
NULL,//0x01d1
NULL,//0x01d2
NULL,//0x01d3
NULL,//0x01d4
NULL,//0x01d5
NULL,//0x01d6
NULL,//0x01d7
NULL,//0x01d8
NULL,//0x01d9
NULL,//0x01da
NULL,//0x01db
NULL,//0x01dc
NULL,//0x01dd
NULL,//0x01de
NULL,//0x01df
NULL,/* 0x01E0 */
NULL,//0x01e1
NULL,//0x01e2
L"MN_SETHMENU",//0x01e3
L"MN_GETHMENU",//0x01e4
L"MN_SIZEWINDOW",//0x01e5
L"MN_OPENHIERARCHY",//0x01e6
L"MN_CLOSEHIERARCHY",//0x01e7
L"MN_SELECTITEM",//0x01e8
L"MN_CANCELMENUS",//0x01e9
L"MN_SELECTFIRSTVALIDITEM",//0x01ea
NULL,//0x01eb
NULL,//0x01ec
NULL,//0x01ed
L"MN_FINDMENUWINDOWFROMPOINT",//0x01ee
L"MN_SHOWPOPUPWINDOW",//0x01ef
L"MN_BUTTONUP",//0x01f0
L"MN_SETTIMERTOOPENHIERARCHY",//0x01f1
L"MN_DBLCLK",//0x01f2
L"MN_ACTIVEPOPUP",//0x01f3
L"MN_ENDMENU",//0x01f4
L"MN_DODRAGDROP",//0x01f5
NULL,//0x01f6
NULL,//0x01f7
NULL,//0x01f8
NULL,//0x01f9
NULL,//0x01fa
NULL,//0x01fb
NULL,//0x01fc
NULL,//0x01fd
NULL,//0x01fe
NULL,//0x01ff
};
#include "WindowsMessages.h"
wchar_t* get_msg_name(int message)
{
static wchar_t str[64];
if ( message<0 || message>(sizeof(Messages) / sizeof(wchar_t) ))
{
wsprintf(str, L"未收录消息:%X", message);
return str;
}
wchar_t* msg = Messages[message];
if (msg == NULL)
{
wsprintf(str, L"不明消息:%X", message);
return str;
}
return msg;
}
//Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 1 /// Summary description for ProcessUtils.
public static class ProcessUtils
{
private static Mutex mutex = null;
/// Determine if the current process is already running
public static bool ThisProcessIsAlreadyRunning()
{
// Only want to call this method once, at startup.
Debug.Assert(mutex == null);
// createdNew needs to be false in .Net 2.0, otherwise, if another instance of
// this program is running, the Mutex constructor will block, and then throw
// an exception if the other instance is shut down.
bool createdNew = false;
mutex = new Mutex(false, Application.ProductName, out createdNew);
Debug.Assert(mutex != null);
return !createdNew;
}
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_RESTORE = 9;
[DllImport("user32.dll")]
static extern IntPtr GetLastActivePopup(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool IsWindowEnabled(IntPtr hWnd);
/// Set focus to the previous instance of the specified program.
public static void SetFocusToPreviousInstance(string windowCaption)
{
// Look for previous instance of this program.
IntPtr hWnd = FindWindow(null, windowCaption);
// If a previous instance of this program was found...
if (hWnd != null)
{
// Is it displaying a popup window?
IntPtr hPopupWnd = GetLastActivePopup(hWnd);
// If so, set focus to the popup window. Otherwise set focus
// to the program's main window.
if (hPopupWnd != null && IsWindowEnabled(hPopupWnd))
{
hWnd = hPopupWnd;
}
SetForegroundWindow(hWnd);
// If program is minimized, restore it.
if (IsIconic(hWnd))
{
ShowWindow(hWnd, SW_RESTORE);
}
}
}
}
struct Win32
{
public const string TOOLBARCLASSNAME = "ToolbarWindow32";
public const int WS_CHILD = 0x40000000;
public const int WS_VISIBLE = 0x10000000;
public const int WS_CLIPCHILDREN = 0x2000000;
public const int WS_CLIPSIBLINGS = 0x4000000;
public const int WS_BORDER = 0x800000;
public const int CCS_NODIVIDER = 0x40;
public const int CCS_NORESIZE = 0x4;
public const int CCS_NOPARENTALIGN = 0x8;
public const int I_IMAGECALLBACK = -1;
public const int I_IMAGENONE = -2;
public const int TBSTYLE_TOOLTIPS = 0x100;
public const int TBSTYLE_FLAT = 0x800;
public const int TBSTYLE_LIST = 0x1000;
public const int TBSTYLE_TRANSPARENT = 0x8000;
public const int TBSTYLE_EX_DRAWDDARROWS = 0x1;
public const int TBSTYLE_EX_HIDECLIPPEDBUTTONS = 0x10;
public const int TBSTYLE_EX_DOUBLEBUFFER = 0x80;
public const int CDRF_DODEFAULT = 0x0;
public const int CDRF_SKIPDEFAULT = 0x4;
public const int CDRF_NOTIFYITEMDRAW = 0x20;
public const int CDDS_PREPAINT = 0x1;
public const int CDDS_ITEM = 0x10000;
public const int CDDS_ITEMPREPAINT = CDDS_ITEM | CDDS_PREPAINT;
public const int CDIS_HOT = 0x40;
public const int CDIS_SELECTED = 0x1;
public const int CDIS_DISABLED = 0x4;
public const int WM_SETREDRAW = 0x000B;
public const int WM_CANCELMODE = 0x001F;
public const int WM_NOTIFY = 0x4e;
public const int WM_KEYDOWN = 0x100;
public const int WM_KEYUP = 0x101;
public const int WM_CHAR = 0x0102;
public const int WM_SYSKEYDOWN = 0x104;
public const int WM_SYSKEYUP = 0x105;
public const int WM_COMMAND = 0x111;
public const int WM_MENUCHAR = 0x120;
public const int WM_MOUSEMOVE = 0x200;
public const int WM_LBUTTONDOWN = 0x201;
public const int WM_MOUSELAST = 0x20a;
public const int WM_USER = 0x0400;
public const int WM_REFLECT = WM_USER + 0x1c00;
public const int NM_CUSTOMDRAW = -12;
public const int TTN_NEEDTEXTA = ((0-520)-0);
public const int TTN_NEEDTEXTW = ((0-520)-10);
public const int TBN_QUERYINSERT = ((0-700)-6);
public const int TBN_DROPDOWN = ((0-700)-10);
public const int TBN_HOTITEMCHANGE = ((0 - 700) - 13);
public const int TBIF_IMAGE = 0x1;
public const int TBIF_TEXT = 0x2;
public const int TBIF_STATE = 0x4;
public const int TBIF_STYLE = 0x8;
public const int TBIF_COMMAND = 0x20;
public const int MNC_EXECUTE = 2;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class INITCOMMONCONTROLSEX
{
public int dwSize = 8;
public int dwICC;
}
public const int ICC_BAR_CLASSES = 4;
public const int ICC_COOL_CLASSES = 0x400;
[DllImport("comctl32.dll")]
public static extern bool InitCommonControlsEx(INITCOMMONCONTROLSEX icc);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr hwndFrom;
public int idFrom;
public int code;
}
[StructLayout(LayoutKind.Sequential)]
public struct NMTOOLBAR
{
public NMHDR hdr;
public int iItem;
public TBBUTTON tbButton;
public int cchText;
public IntPtr pszText;
}
[StructLayout(LayoutKind.Sequential)]
public struct NMCUSTOMDRAW
{
public NMHDR hdr;
public int dwDrawStage;
public IntPtr hdc;
public RECT rc;
public int dwItemSpec;
public int uItemState;
public int lItemlParam;
}
[StructLayout(LayoutKind.Sequential)]
public struct LPNMTBCUSTOMDRAW
{
public NMCUSTOMDRAW nmcd;
public IntPtr hbrMonoDither;
public IntPtr hbrLines;
public IntPtr hpenLines;
public int clrText;
public int clrMark;
public int clrTextHighlight;
public int clrBtnFace;
public int clrBtnHighlight;
public int clrHighlightHotTrack;
public RECT rcText;
public int nStringBkMode;
public int nHLStringBkMode;
}
public const int TTF_RTLREADING = 0x0004;
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct TOOLTIPTEXT
{
public NMHDR hdr;
public IntPtr lpszText;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=80)]
public string szText;
public IntPtr hinst;
public int uFlags;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct TOOLTIPTEXTA
{
public NMHDR hdr;
public IntPtr lpszText;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=80)]
public string szText;
public IntPtr hinst;
public int uFlags;
}
public const int TB_PRESSBUTTON = WM_USER + 3;
public const int TB_INSERTBUTTON = WM_USER + 21;
public const int TB_BUTTONCOUNT = WM_USER + 24;
public const int TB_GETITEMRECT = WM_USER + 29;
public const int TB_BUTTONSTRUCTSIZE = WM_USER + 30;
public const int TB_SETBUTTONSIZE = WM_USER + 32;
public const int TB_SETIMAGELIST = WM_USER + 48;
public const int TB_GETRECT = WM_USER + 51;
public const int TB_SETBUTTONINFO = WM_USER + 64;
public const int TB_HITTEST = WM_USER +69;
public const int TB_GETHOTITEM = WM_USER + 71;
public const int TB_SETHOTITEM = WM_USER + 72;
public const int TB_SETEXTENDEDSTYLE = WM_USER + 84;
public const int TBSTATE_CHECKED = 0x01;
public const int TBSTATE_ENABLED = 0x04;
public const int TBSTATE_HIDDEN = 0x08;
public const int BTNS_BUTTON = 0;
public const int BTNS_SEP = 0x1;
public const int BTNS_DROPDOWN = 0x8;
public const int BTNS_AUTOSIZE = 0x10;
public const int BTNS_WHOLEDROPDOWN = 0x80;
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct TBBUTTON
{
public int iBitmap;
public int idCommand;
public byte fsState;
public byte fsStyle;
public byte bReserved0;
public byte bReserved1;
public int dwData;
public int iString;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct TBBUTTONINFO
{
public int cbSize;
public int dwMask;
public int idCommand;
public int iImage;
public byte fsState;
public byte fsStyle;
public short cx;
public IntPtr lParam;
public IntPtr pszText;
public int cchText;
}
[DllImport("user32.dll", ExactSpelling=true, CharSet=CharSet.Auto)]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern void SendMessage(IntPtr hWnd, int msg, int wParam, ref RECT lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref POINT lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern void SendMessage(IntPtr hWnd, int msg, int wParam, ref TBBUTTON lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern void SendMessage(IntPtr hWnd, int msg, int wParam, ref TBBUTTONINFO lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern void SendMessage(IntPtr hWnd, int msg, int wParam, ref REBARBANDINFO lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);
[DllImport("kernel32.dll", ExactSpelling=true, CharSet=CharSet.Auto)]
public static extern int GetCurrentThreadId();
public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
public const int WH_MSGFILTER = -1;
public const int MSGF_MENU = 2;
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SetWindowsHookEx(int hookid, HookProc pfnhook, IntPtr hinst, int threadid);
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern bool UnhookWindowsHookEx(IntPtr hhook);
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern IntPtr CallNextHookEx(IntPtr hhook, int code, IntPtr wparam, IntPtr lparam);
[StructLayout(LayoutKind.Sequential)]
public struct MSG
{
public IntPtr hwnd;
public int message;
public IntPtr wParam;
public IntPtr lParam;
public int time;
public int pt_x;
public int pt_y;
}
public const string REBARCLASSNAME = "ReBarWindow32";
public const int RBS_VARHEIGHT = 0x200;
public const int RBS_BANDBORDERS = 0x400;
public const int RBS_AUTOSIZE = 0x2000;
public const int RBN_FIRST = -831;
public const int RBN_HEIGHTCHANGE = RBN_FIRST - 0;
public const int RBN_AUTOSIZE = RBN_FIRST - 3;
public const int RBN_CHEVRONPUSHED = RBN_FIRST - 10;
public const int RB_SETBANDINFO = WM_USER + 6;
public const int RB_GETRECT = WM_USER + 9;
public const int RB_INSERTBAND = WM_USER + 10;
public const int RB_GETBARHEIGHT = WM_USER + 27;
[StructLayout(LayoutKind.Sequential)]
public struct REBARBANDINFO
{
public int cbSize;
public int fMask;
public int fStyle;
public int clrFore;
public int clrBack;
public IntPtr lpText;
public int cch;
public int iImage;
public IntPtr hwndChild;
public int cxMinChild;
public int cyMinChild;
public int cx;
public IntPtr hbmBack;
public int wID;
public int cyChild;
public int cyMaxChild;
public int cyIntegral;
public int cxIdeal;
public int lParam;
public int cxHeader;
}
public const int RBBIM_CHILD = 0x10;
public const int RBBIM_CHILDSIZE = 0x20;
public const int RBBIM_STYLE = 0x1;
public const int RBBIM_ID = 0x100;
public const int RBBIM_SIZE = 0x40;
public const int RBBIM_IDEALSIZE = 0x200;
public const int RBBIM_TEXT = 0x4;
public const int RBBS_BREAK = 0x1;
public const int RBBS_CHILDEDGE = 0x4;
public const int RBBS_FIXEDBMP = 0x20;
public const int RBBS_GRIPPERALWAYS = 0x80;
public const int RBBS_USECHEVRON = 0x200;
[StructLayout(LayoutKind.Sequential)]
public struct NMREBARCHEVRON
{
public NMHDR hdr;
public int uBand;
public int wID;
public int lParam;
public RECT rc;
public int lParamNM;
}
[StructLayout(LayoutKind.Sequential)]
public struct IMAGELISTDRAWPARAMS
{
public int cbSize;
public IntPtr himl;
public int i;
public IntPtr hdcDst;
public int x;
public int y;
public int cx;
public int cy;
public int xBitmap;
public int yBitmap;
public int rgbBk;
public int rgbFg;
public int fStyle;
public int dwRop;
public int fState;
public int Frame;
public int crEffect;
}
public const int ILD_TRANSPARENT = 0x1;
public const int ILS_SATURATE = 0x4;
[DllImport("comctl32.dll", CharSet=CharSet.Auto)]
public static extern bool ImageList_DrawIndirect(ref IMAGELISTDRAWPARAMS pimldp);
[StructLayout(LayoutKind.Sequential)]
public struct DLLVERSIONINFO
{
public int cbSize;
public int dwMajorVersion;
public int dwMinorVersion;
public int dwBuildNumber;
public int dwPlatformID;
}
[DllImport("comctl32.dll")]
public extern static int DllGetVersion(ref DLLVERSIONINFO dvi);
public const int SPI_GETFLATMENU = 0x1022;
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public extern static int SystemParametersInfo(int nAction, int nParam, ref int value, int ignore);
public const int DT_SINGLELINE = 0x20;
public const int DT_LEFT = 0x0;
public const int DT_VCENTER = 0x4;
public const int DT_CALCRECT = 0x400;
[DllImport("user32.dll")]
public extern static int DrawText(IntPtr hdc, string lpString, int nCount, ref RECT lpRect, int uFormat);
public const int TRANSPARENT = 1;
[DllImport("gdi32.dll")]
public extern static int SetBkMode(IntPtr hdc, int iBkMode);
[DllImport("gdi32.dll")]
public extern static int SetTextColor(IntPtr hdc, int crColor);
[DllImport("gdi32.dll")]
public extern static IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("gdi32.dll", ExactSpelling=true, CharSet=CharSet.Auto)]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("user32.dll", ExactSpelling=true, CharSet=CharSet.Auto)]
public static extern bool MessageBeep(int type);
public class TextHelper
{
public static Size GetTextSize(Graphics graphics, string text, Font font)
{
IntPtr hdc = graphics.GetHdc();
IntPtr fontHandle = font.ToHfont();
IntPtr currentFontHandle = Win32.SelectObject(hdc, fontHandle);
Win32.RECT rect = new Win32.RECT();
rect.left = 0;
rect.right = 0;
rect.top = 0;
rect.bottom = 0;
Win32.DrawText(hdc, text, text.Length, ref rect, Win32.DT_SINGLELINE | Win32.DT_LEFT | Win32.DT_CALCRECT);
Win32.SelectObject(hdc, currentFontHandle);
Win32.DeleteObject(fontHandle);
graphics.ReleaseHdc(hdc);
return new Size(rect.right - rect.left, rect.bottom - rect.top);
}
public static void DrawText(Graphics graphics, string text, Point point, Font font, Color color)
{
Size size = GetTextSize(graphics, text, font);
IntPtr hdc = graphics.GetHdc();
IntPtr fontHandle = font.ToHfont();
IntPtr currentFontHandle = Win32.SelectObject(hdc, fontHandle);
int currentBkMode = Win32.SetBkMode(hdc, Win32.TRANSPARENT);
int currentCrColor = Win32.SetTextColor(hdc, Color.FromArgb(0, color.R, color.G, color.B).ToArgb());
Win32.RECT rc = new Win32.RECT();
rc.left = point.X;
rc.top = point.Y;
rc.right = rc.left + size.Width;
rc.bottom = rc.top + size.Height;
Win32.DrawText(hdc, text, text.Length, ref rc, Win32.DT_SINGLELINE | Win32.DT_LEFT);
Win32.SetTextColor(hdc, currentCrColor);
Win32.SetBkMode(hdc, currentBkMode);
Win32.SelectObject(hdc, currentFontHandle);
Win32.DeleteObject(fontHandle);
graphics.ReleaseHdc(hdc);
}
}
public class ImageHelper
{
static Version version = null;
static ImageHelper()
{
Win32.DLLVERSIONINFO dvi = new Win32.DLLVERSIONINFO();
dvi.cbSize = Marshal.SizeOf(typeof(Win32.DLLVERSIONINFO));
Win32.DllGetVersion(ref dvi);
version = new Version(dvi.dwMajorVersion, dvi.dwMinorVersion, dvi.dwBuildNumber, 0);
}
public static Version Version
{
get { return version; }
}
public static void DrawImage(Graphics graphics, Image image, Point point, bool disabled)
{
if (!disabled)
{
graphics.DrawImage(image, point);
return;
}
// Painting a disabled gray scale image is done using ILS_SATURATE on WinXP.
// This code emulates that behaviour if comctl32 version 6 is not availble.
if (version.Major < 6)
{
ImageAttributes attributes = new ImageAttributes();
Rectangle destination = new Rectangle(point, image.Size);
float[][] matrix = new float[5][];
matrix[0] = new float[] { 0.2222f, 0.2222f, 0.2222f, 0.0000f, 0.0000f };
matrix[1] = new float[] { 0.2222f, 0.2222f, 0.2222f, 0.0000f, 0.0000f };
matrix[2] = new float[] { 0.2222f, 0.2222f, 0.2222f, 0.0000f, 0.0000f };
matrix[3] = new float[] { 0.3333f, 0.3333f, 0.3333f, 0.7500f, 0.0000f };
matrix[4] = new float[] { 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f };
attributes.SetColorMatrix(new ColorMatrix(matrix));
graphics.DrawImage(image, destination, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
}
else
{
ImageList imageList = new ImageList();
imageList.ImageSize = image.Size;
imageList.ColorDepth = ColorDepth.Depth32Bit;
imageList.Images.Add(image);
IntPtr hdc = graphics.GetHdc();
Win32.IMAGELISTDRAWPARAMS ildp = new Win32.IMAGELISTDRAWPARAMS();
ildp.cbSize = Marshal.SizeOf(typeof(Win32.IMAGELISTDRAWPARAMS));
ildp.himl = imageList.Handle;
ildp.i = 0; // image index
ildp.hdcDst = hdc;
ildp.x = point.X;
ildp.y = point.Y;
ildp.cx = 0;
ildp.cy = 0;
ildp.xBitmap = 0;
ildp.yBitmap = 0;
ildp.fStyle = Win32.ILD_TRANSPARENT;
ildp.fState = Win32.ILS_SATURATE;
ildp.Frame = -100;
Win32.ImageList_DrawIndirect(ref ildp);
graphics.ReleaseHdc(hdc);
return;
}
}
}
}
#pragma once
/*
日志记录类
功能描述:
根据当前时间自动生成日志文件名,自动记录日志到日志文件。
日志文件名格式(样例):
20141219211252255.log
日志内容格式(样例):
2014年12月19日11时52分55秒,源文件:e:\work\udptest\udptestdlg.cpp,第109行, 这里是要写的日志内容
使用方式:
此类采用单例模式设计,为使用方便,定义了两个宏供用户调用。样例代码:
LOG(L"这里是要写的日志内容"); // 记录日志到文件
ENDLOG // 程序退出之前调用,关闭日志文件
*/
class LogWriter
{
protected:
LogWriter();
~LogWriter();
private:
wchar_t fileName[1024];
FILE* fp;
public:
void Log(wchar_t* log);
public:
static LogWriter* GetLogWriter();
static void DeleteLogWriter();
private:
static LogWriter* theOnlyLogWriter;
};
#define LOG(x) \
{ \
wchar_t buffer[2048];\
SYSTEMTIME st;\
::GetLocalTime(&st);\
swprintf_s(buffer, L"%04d年%02d月%02d日%02d时%02d分%02d秒,源文件:%s,第%d行, %s\n", \
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond,\
TEXT(__FILE__),__LINE__,x);\
LogWriter::GetLogWriter()->Log(buffer);\
}
#define ENDLOG \
LogWriter::DeleteLogWriter();
#include "stdafx.h"
#include "LogWriter.h"
#include "share.h"
LogWriter* LogWriter::theOnlyLogWriter = NULL;
LogWriter::LogWriter()
{
// determine the log file's name, yyyyMMddhhmmss.log
SYSTEMTIME st;
::GetLocalTime(&st);
::swprintf_s(this->fileName, L"%04d%02d%02d%02d%02d%02d.log", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
fp = ::_wfsopen(this->fileName, L"w,ccs=UTF-8", _SH_DENYNO); // 以共享读写模式打开日志文件
}
// 线程安全的写入文件
void LogWriter::Log(wchar_t* log)
{
if (fp != NULL)
{
::fwprintf(this->fp, L"%s", log);
}
}
LogWriter::~LogWriter()
{
if (this->fp != NULL)
::fclose(fp);
}
LogWriter* LogWriter::GetLogWriter()
{
if (theOnlyLogWriter == NULL)
{
theOnlyLogWriter = new LogWriter();
}
return theOnlyLogWriter;
}
void LogWriter::DeleteLogWriter()
{
if (theOnlyLogWriter != NULL)
{
delete theOnlyLogWriter;
theOnlyLogWriter = NULL;
}
}
#pragma once
#include
#include
#include
#pragma comment(lib, "IPHLPAPI.lib")
#pragma comment(lib, "WS2_32")
#include
using namespace std;
typedef void(*UDPRecvFun)(void* sender, BYTE*, int); // 收到UDP数据包后的回调函数原型
/*
UDP服务器类
功能描述:
建立UDP侦听,建立一个专用线程负责接收UDP数据包。该类采用类似于C#的事件驱动设计模式。
使用样例:
void AfterRecv(void* sender, BYTE* data, int len) // 回调函数实现
{
......
}
UDPServer pServer = new UDPServer("127.0.0.1", 8888);
pServer.AddCallback(AfterRecv); // 增加一个回调, 收到UDP包后会自动调用此函数
pServer->StartUDPServer(); // 开始侦听
pServer->StopUDPServer(); // 可选,因为析构函数会自动调用此方法
delete pServer;
*/
class UDPServer
{
public:
UDPServer(unsigned int ip, unsigned short port);
UDPServer(char* ip, unsigned short port);
~UDPServer();
protected:
static DWORD WINAPI UDPServerThreadFunc(void* state);
void StartUDPServer(unsigned int ip, unsigned short port);
void StartUDPServer(char* ip, unsigned short port);
void OnRecv(BYTE*, int);
private:
unsigned long IP;
unsigned short port;
SOCKET sock; // socket
HANDLE tid; // 侦听线程ID
CRITICAL_SECTION cs; // 线程同步用
int isEnd; // 是否终止侦听
vector listOnRecv; // 收到UDP包后的回调函数列表
public:
SOCKET GetSocket(){ return this->sock; }
protected:
int GetIsEnd();
void SetIsEnd(int n);
public:
void StartUDPServer();
void StopUDPServer();
void AddCallback(UDPRecvFun cb); // 增加一个回调函数
};
#include "stdafx.h"
#include "UDPServer.h"
#include "LogWriter.h"
UDPServer::UDPServer(unsigned int ip, unsigned short port)
{
this->sock = NULL;
this->tid = NULL;
this->listOnRecv.clear();
this->IP = ip;
this->port = port;
::InitializeCriticalSection(&this->cs);
isEnd = 0;
}
UDPServer::UDPServer(char* ip, unsigned short port)
{
this->sock = NULL;
this->tid = NULL;
this->listOnRecv.clear();
this->IP = ::inet_addr(ip);
this->port = port;
::InitializeCriticalSection(&this->cs);
isEnd = 0;
}
UDPServer::~UDPServer()
{
if (this->tid != NULL)
{
StopUDPServer();
}
::DeleteCriticalSection(&this->cs);
}
/*
功能:线程安全地设置isEnd
*/
void UDPServer::SetIsEnd(int n)
{
::EnterCriticalSection(&this->cs);
this->isEnd = n;
::LeaveCriticalSection(&this->cs);
}
/*
功能: 线程安全地读取isEnd
*/
int UDPServer::GetIsEnd()
{
::EnterCriticalSection(&this->cs);
int r = this->isEnd;
::LeaveCriticalSection(&this->cs);
return r;
}
/*
功能:停止UDP服务器(线程)
*/
void UDPServer::StopUDPServer()
{
if (this->tid != NULL)
{
this->SetIsEnd(1); // 设置停止标记
::closesocket(this->sock);// 唤醒recvfrom() //::shutdown(this->sock, SD_BOTH); 不好用
this->sock = NULL;
::WaitForSingleObject(this->tid, INFINITE);// 等待UDP专用线程结束
this->tid = NULL;
}
}
/*
功能:调用回调列表里的所有函数
*/
void UDPServer::OnRecv(BYTE* data, int len)
{
vector::iterator it;
for (it = this->listOnRecv.begin(); it != this->listOnRecv.end(); it++)
{
if (*it != NULL)
{
(*it)(this, data, len);
}
}
}
/*
功能:启动UDP侦听服务器
参数:ip-侦听IP字符串; port-侦听端口
*/
void UDPServer::StartUDPServer(char* ip, unsigned short port)
{
unsigned long nIP = ::inet_addr(ip);
if (nIP == INADDR_NONE)
{
LOG(L"IP 地址%s 错误");
return;
}
this->StartUDPServer(nIP, port);
}
/*
线程函数传参结构,用于安全地向子线程传参
*/
class UDPThreadState
{
public:
UDPServer* obj;
SOCKET scok;
};
/*
功能:开启UDP侦听线程, 本函数不阻塞
参数:ip - 侦听IP,port-侦听端口
*/
void UDPServer::StartUDPServer(unsigned int ip, unsigned short port)
{
if (this->sock != NULL) return;
this->sock = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET)
{
this->sock = NULL;
LOG(L"UDP服务器创建socket失败");
return;
}
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.S_un.S_addr = ip;
if (::bind(sock, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
LOG(L"bind() failed");
return;
}
wchar_t log[1024];
swprintf_s(log, L"UDP服务器绑定到了 %S:%d",
::inet_ntoa(sin.sin_addr), ::ntohs(sin.sin_port)); // 注意%S与%s
LOG(log);
UDPThreadState* state = new UDPThreadState();
state->obj = this;
state->scok = sock;
this->tid = ::CreateThread(NULL, 0, UDPServerThreadFunc, (void*)state, NULL, NULL);
if (tid == NULL)
{
delete state;
}
}
/*
功能:UDP 侦听线程函数,静态函数
参数:符合ThreadProc规范要求
*/
DWORD UDPServer::UDPServerThreadFunc(void* state)
{
// 解析线程函数参数
UDPThreadState* pstate = (UDPThreadState*)state;
UDPServer* obj = pstate->obj;
SOCKET sockServer = pstate->scok;
delete pstate; pstate = NULL;
wchar_t log[100];
swprintf_s(log, L"UDP侦听线程 %d 已经启动", ::GetCurrentThreadId());
LOG(log);
char buff[1024];
sockaddr_in remoteAddr;
int nLen = sizeof(remoteAddr);
while (1)
{
if (1 == obj->GetIsEnd())
{
break;
}
int n = ::recvfrom(sockServer, buff, 1024, 0, (sockaddr*)&remoteAddr, &nLen);
if (n == SOCKET_ERROR)
{
wchar_t log[128];
swprintf_s(log, L"recvfrom返回错误号:%d", ::WSAGetLastError());
LOG(log);
}
else if (n == 0)
{
LOG(L"socket关闭,recvfrom() 退出");
}
else
{
wchar_t log[128];
swprintf_s(log, L"接收到UDP包, 大小%d字节,来自%S:%d",
n, ::inet_ntoa(remoteAddr.sin_addr), ::ntohs(remoteAddr.sin_port)); // 注意%S与%s
LOG(log);
obj->OnRecv((BYTE*)buff, n);
}
}
swprintf_s(log, L"UDP侦听线程 %d 退出", ::GetCurrentThreadId());
LOG(log);
return 0;
}
/*
功能:启动侦听
*/
void UDPServer::StartUDPServer()
{
this->StartUDPServer(this->IP, this->port);
}
/*
功能:向回调函数链表中增加一个回调函数
参数:cb-用户定义的回调函数名
*/
void UDPServer::AddCallback(UDPRecvFun cb)
{
this->listOnRecv.push_back(cb);
}
Radar::Radar()
{
// 建立服务器1
this->pUDPServer = new UDPServer(”172.16.35.144", 8888);
this->pUDPServer->AddCallback(Radar::AfterRecvUDP);
// 建立服务器2
pUDPServer2 = new UDPServer("172.16.35.144", 9999);
pUDPServer2->AddCallback(Radar::AfterRecvUDP);
}
// 回调函数
void Radar::AfterRecvUDP(void* sender, BYTE* data, int len)
{
data[len] = 0;
::MessageBoxA(::AfxGetApp()->GetMainWnd()->m_hWnd, (char*)data, "C", MB_OK);
}
#pragma once
/********************************************************************************
WindowPrinter 打印窗口类
功能描述:
提供截屏窗口并通过默认打印机,自动进行居中缩放打印
使用说明:
样例代码如下。
HWND hwnd = this->GetSafeWnd();
WindowPrinter::PrintWindowClientArea(hwnd);
********************************************************************************/
class WindowPrinter
{
public:
WindowPrinter();
~WindowPrinter();
public:
/*
功能:获取当前默认打印机的DC
返回:成功返回打印机的DC,失败返回NULL
*/
static HDC GetPrinterDC();
/*
功能:打印窗口客户区内容到打印机,自动缩放居中打印
参数: hWnd-被打印窗口的句柄
*/
static void PrintWindowClientArea(HWND hwnd);
};
#include "stdafx.h"
#include "WindowPrinter.h"
#include
WindowPrinter::WindowPrinter()
{
}
WindowPrinter::~WindowPrinter()
{
}
/*
功能:获取当前默认打印机的DC
返回:成功返回打印机的DC,失败返回NULL
*/
HDC WindowPrinter::GetPrinterDC()
{
DWORD dwNeeded, dwReturned;
HDC hdc;
::EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwNeeded, &dwReturned);
PRINTER_INFO_4* pinfo4 = (PRINTER_INFO_4*)malloc(dwNeeded);
::EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, (BYTE*)pinfo4, dwNeeded, &dwNeeded, &dwReturned);
hdc = ::CreateDC(NULL, pinfo4->pPrinterName, NULL, NULL);
free(pinfo4);
return hdc;
}
/*
功能:打印窗口客户区内容到打印机,自动缩放居中打印
参数: hWnd-被打印窗口的句柄
*/
void WindowPrinter::PrintWindowClientArea(HWND hWnd)
{
if (hWnd == NULL) return;
RECT rectClient;
::GetClientRect(hWnd, &rectClient);
int width = rectClient.right - rectClient.left;
int height = rectClient.bottom - rectClient.top;
// 通过内存DC复制客户区到DDB位图
HDC hdcWnd = ::GetDC(hWnd);
HBITMAP hbmWnd = ::CreateCompatibleBitmap(hdcWnd, width, height);
HDC hdcMem = ::CreateCompatibleDC(hdcWnd);
::SelectObject(hdcMem, hbmWnd);
::BitBlt(hdcMem, 0, 0, width, height, hdcWnd, 0, 0, SRCCOPY);
// 把窗口DDB转为DIB
BITMAP bmpWnd;
::GetObject(hbmWnd, sizeof(BITMAP), &bmpWnd);
BITMAPINFOHEADER bi; // 信息头
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmpWnd.bmWidth;
bi.biHeight = bmpWnd.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32; // 按照每个像素用32bits表示转换
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((bmpWnd.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpWnd.bmHeight; // 每一行像素位32对齐
char *lpbitmap = (char*)malloc(dwBmpSize); // 像素位指针
::GetDIBits(hdcMem, hbmWnd, 0, (UINT)bmpWnd.bmHeight,
lpbitmap,
(BITMAPINFO*)&bi,
DIB_RGB_COLORS);
::DeleteDC(hdcMem);
::DeleteObject(hbmWnd);
::ReleaseDC(hWnd, hdcWnd);
// 存为文件(可选)
BITMAPFILEHEADER bmfHeader; // 文件头
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
bmfHeader.bfSize = dwSizeofDIB;
bmfHeader.bfType = 0x4D42;
FILE* fp = NULL;
::_wfopen_s(&fp, L"capture.bmp", L"w");
::fwrite(&bmfHeader, sizeof(BITMAPFILEHEADER), 1, fp); // 写入文件头
::fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, fp); // 写入信息头
::fwrite(lpbitmap, dwBmpSize, 1, fp); // 写入像素位
::fclose(fp);
fp = NULL;
// StretchDIBits()缩放打印DIB
HDC hdcPrinter = WindowPrinter::GetPrinterDC();
if (hdcPrinter == NULL)
return;
int pageWidth = ::GetDeviceCaps(hdcPrinter, HORZRES);
int pageHeight = ::GetDeviceCaps(hdcPrinter, VERTRES);
float scaleX = (float)pageWidth / (float)bmpWnd.bmWidth;
float scaleY = (float)pageHeight / (float)bmpWnd.bmHeight;
float scale = scaleX < scaleY ? scaleX : scaleY;
int xDst, yDst, cxDst, cyDst;
cxDst = (int)((float)bmpWnd.bmWidth * scale);
cyDst = (int)((float)bmpWnd.bmHeight * scale);
xDst = (int)((pageWidth - cxDst) / 2);
yDst = (int)((pageHeight - cyDst) / 2);
static DOCINFO di = { sizeof(DOCINFO), L"PRINTJOBNAME" };
if (::StartDoc(hdcPrinter, &di) > 0)
{
if (::StartPage(hdcPrinter) > 0)
{
::StretchDIBits(hdcPrinter,
xDst, yDst, cxDst, cyDst,
0, 0, bmpWnd.bmWidth, bmpWnd.bmHeight,
lpbitmap,
(BITMAPINFO*)&bi,
DIB_RGB_COLORS,
SRCCOPY);
::EndPage(hdcPrinter);
}
::EndDoc(hdcPrinter);
}
::DeleteDC(hdcPrinter);
::free(lpbitmap);
}
#include
#ifndef _HOOKAPI_H
#define _HOOKAPI_H
class CHOOKAPI {
public:
LPVOID pOldFunEntry, pNewFunEntry ; // 初始函数地址、HOOK后的函数地址
BYTE bOldByte[5], bNewByte[5] ; // 原始字节、目标字节
public:
CHOOKAPI () {}
~CHOOKAPI() {}
// 实现HOOK API
void Hook ( PSTR szModuleName, PSTR szFunName, FARPROC pFun )
{
HMODULE hMod = ::GetModuleHandleA ( szModuleName ) ;
if ( hMod != NULL )
{
pNewFunEntry = (LPVOID)pFun ;
pOldFunEntry = (LPVOID)GetProcAddress ( hMod, szFunName ) ;
bNewByte[0] = 0xE9 ;
*((PDWORD)(&(bNewByte[1]))) = (DWORD)pNewFunEntry - (DWORD)pOldFunEntry - 5 ;
DWORD dwProtect, dwWriteByte, dwReadByte ;
VirtualProtect ( (LPVOID)pOldFunEntry, 5, PAGE_READWRITE, &dwProtect );
ReadProcessMemory ( GetCurrentProcess(), (LPVOID)pOldFunEntry, bOldByte, 5, &dwReadByte ) ;
WriteProcessMemory ( GetCurrentProcess(), (LPVOID)pOldFunEntry, bNewByte, 5, &dwWriteByte ) ;
VirtualProtect ( (LPVOID)pOldFunEntry, 5, dwProtect, NULL ) ;
}
}
// 重新HOOK
void ReHook ()
{
DWORD dwProtect, dwWriteByte ;
VirtualProtect ( pOldFunEntry, 5, PAGE_READWRITE, &dwProtect );
WriteProcessMemory ( GetCurrentProcess(), pOldFunEntry, bNewByte, 5, &dwWriteByte ) ;
VirtualProtect ( pOldFunEntry, 5, dwProtect, NULL ) ;
}
// 撤消HOOK
void UnHook ()
{
DWORD dwProtect, dwWriteByte ;
VirtualProtect ( pOldFunEntry, 5, PAGE_READWRITE, &dwProtect );
WriteProcessMemory ( GetCurrentProcess(), pOldFunEntry, bOldByte, 5, &dwWriteByte ) ;
VirtualProtect ( pOldFunEntry, 5, dwProtect, NULL ) ;
}
} ;
#endif
#include "stdafx.h"
#include "HookApi.h"
CHOOKAPI HookItem ;
// 定义MessageBoxA函数原型
typedef int (WINAPI* PFNMessageBoxA)( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ) ;
// 自定义的MessageBoxA函数
// 实现对原始MessageBoxA的输入、输出参数的监控,甚至是取消调用
int WINAPI New_MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType )
{
// 撤消HOOK
HookItem.UnHook () ;
// 此处可以观察/修改调用参数,甚至可以取消调用直接返回。
// ……
// 取得原函数地址
PFNMessageBoxA pfnMessageBoxA = (PFNMessageBoxA)HookItem.pOldFunEntry ;
// 调用原函数,修改输入参数
int ret = pfnMessageBoxA ( hWnd, "这是HOOK函数过程的消息框", "[测试]", uType ) ;
// 此处可以查看/修改调用原函数的返回值
// ……
// 重新HOOK
HookItem.ReHook () ;
return ret ;
}
int main(int argc, char* argv[])
{
// 原始API
MessageBoxA ( 0, "正常消息框", "测试", 0 ) ;
// HOOK API
HookItem.Hook ( "USER32.dll", "MessageBoxA", (FARPROC)New_MessageBoxA ) ;
// 调用API,测试
MessageBoxA ( 0, "正常消息框", "测试", 0 ) ;
// 撤消HOOK
HookItem.UnHook () ;
printf("Hello World!\n");
return 0;
}
#ifndef __WAGuiCtrl_H__
#define __WAGuiCtrl_H__
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#ifndef WINVER
#define WINVER 0x0500
#endif
#include
#include
#include
#include
#include