《Windows程序设计》读书笔八 计时器
发布日期:2021-05-07 23:35:11 浏览次数:13 分类:原创文章

本文共 20480 字,大约阅读时间需要 68 分钟。

第八章  计时器


8.1 计时器的基本知识

WM_TIMER消息

SetTimer

Killtimer

8.1.1 系统和计时器

Timer的底层实现是BIOS的时钟中断(时钟滴答),WinNT上由于系统限制1秒最多响应100次。

8.1.2 计时器消息不是异步的

WM_TIMER消息是低优先级的

一个时钟程序只能通过WM_TIMER消息知道时钟更新了,而不应通过该消息来计算过了多少时间。因为他不是精确的时钟滴答中断


8.2  使用计时器的三种方法

如果程序需要计时器,在winmain 函数或者WM_CREATE消息时,调用SetTimer函数。在离开winMain或者处理WM_DESTORY消息时,调用KillTimer函数。


8.2.1 方法一

SetTimer(hwnd, //窗口句柄

 1, //计数器ID非0

 uiMsecInterval,  //以毫秒为单位的时间间隔

NULL)  // windows将WM_TIMER消息发送到应用程序的窗口过程


KillTimer(hwnd, 1);


WM_TIMER 消息中  wParam 就是计时器的ID

常用法

#define TIMER_SEC 1

#define TIMER_MIN 2


SetTimer(hwnd, TIMER_SEC, 1000, NULL);

SetTimer(hwnd, TIMEr_MIN, 60000, NULL);


case WM_TIMER:

switch(wParam)

{

case TIMER_SEC: 

//do something

break;

case TIMER_MIN:

/do something

break;

}

return 0;


可以改变已有计时器的时间间隔 用SetTimer

一个例子

#include <windows.h>  #define ID_TIMER 1LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,	PSTR szCmdLine, int iCmdShow){	static      TCHAR szAppName[] = TEXT("Beeper1");	HWND        hwnd;	MSG         msg;	WNDCLASS    wndClass;       //The window Class  	wndClass.style = CS_HREDRAW | CS_VREDRAW;	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.  	wndClass.cbClsExtra = 0;	wndClass.cbWndExtra = 0;	wndClass.hInstance = hInstance;	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);	wndClass.lpszMenuName = NULL;	wndClass.lpszClassName = szAppName;	//Register the Window Class to the Windows System.   	if (!RegisterClass(&wndClass))	{		MessageBox(NULL, TEXT("This program require Windows NT!"),			szAppName, MB_ICONERROR);		return 0;	}	//This function will generate an WM_CREATE message.  	hwnd = CreateWindow(szAppName,      //Window class name  		TEXT("Beeper1 Timer Demo"),      //Window caption  		WS_OVERLAPPEDWINDOW,            //Window Style  		CW_USEDEFAULT,                  //initial x position  		CW_USEDEFAULT,                  //initial y position  		CW_USEDEFAULT,                  //initial x size  		CW_USEDEFAULT,                  //initial y size  		NULL,                           //parent window handle  		NULL,                           //window menu handle  		hInstance,                      //program instance handle  		NULL);                          //creation parameters  	ShowWindow(hwnd, iCmdShow);	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.  						/* The message loop for this program.						if received the WM_QUIT message, the function will return 0.*/	while (GetMessage(&msg, NULL, 0, 0))	{		TranslateMessage(&msg);		DispatchMessage(&msg);	}	return msg.wParam;}//define the Window Procedure WndProc  LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){	static BOOL	fFlipFlop = FALSE;	HBRUSH		hBrush;	HDC         hdc;	PAINTSTRUCT ps;	RECT        rc;	switch (message) //get the message  	{	case WM_CREATE:		SetTimer(hwnd, ID_TIMER, 1000, NULL);		return 0;	case WM_TIMER:		MessageBeep(-1);		fFlipFlop = !fFlipFlop;		InvalidateRect(hwnd, NULL, FALSE);		return 0;	case WM_PAINT:		hdc = BeginPaint(hwnd, &ps);		GetClientRect(hwnd, &rc);		hBrush = CreateSolidBrush(fFlipFlop ? RGB(255, 0, 0) : RGB(0, 0, 255));		FillRect(hdc, &rc, hBrush);		DeleteObject(hBrush);		EndPaint(hwnd, &ps);		return 0;	case WM_DESTROY:		KillTimer(hwnd, ID_TIMER);		PostQuitMessage(0);		return 0;	}	return  DefWindowProc(hwnd, message, wParam, lParam);}

运行结果 1秒响应一次Timer 切换窗口客户区的背景颜色为红或蓝



8.2.2 方法二

回调函数


VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)

{

//handle wm_timer message

}


dwTime 记录了windows启动到现在所过去的毫秒数


SetTimer(hwnd, iTimerID, iMsecInterval, TimerProc);


使用TimerProc回调函数来处理WM_TIMER消息的例子

#include <windows.h>  #define ID_TIMER 1LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.  VOID	CALLBACK TimerProc(HWND, UINT, UINT, DWORD);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,	PSTR szCmdLine, int iCmdShow){	static      TCHAR szAppName[] = TEXT("Beeper2");	HWND        hwnd;	MSG         msg;	WNDCLASS    wndClass;       //The window Class  	wndClass.style = CS_HREDRAW | CS_VREDRAW;	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.  	wndClass.cbClsExtra = 0;	wndClass.cbWndExtra = 0;	wndClass.hInstance = hInstance;	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);	wndClass.lpszMenuName = NULL;	wndClass.lpszClassName = szAppName;	//Register the Window Class to the Windows System.   	if (!RegisterClass(&wndClass))	{		MessageBox(NULL, TEXT("This program require Windows NT!"),			szAppName, MB_ICONERROR);		return 0;	}	//This function will generate an WM_CREATE message.  	hwnd = CreateWindow(szAppName,      //Window class name  		TEXT("Beeper2 Timer Demo"),      //Window caption  		WS_OVERLAPPEDWINDOW,            //Window Style  		CW_USEDEFAULT,                  //initial x position  		CW_USEDEFAULT,                  //initial y position  		CW_USEDEFAULT,                  //initial x size  		CW_USEDEFAULT,                  //initial y size  		NULL,                           //parent window handle  		NULL,                           //window menu handle  		hInstance,                      //program instance handle  		NULL);                          //creation parameters  	ShowWindow(hwnd, iCmdShow);	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.  						/* The message loop for this program.						if received the WM_QUIT message, the function will return 0.*/	while (GetMessage(&msg, NULL, 0, 0))	{		TranslateMessage(&msg);		DispatchMessage(&msg);	}	return msg.wParam;}//define the Window Procedure WndProc  LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){	switch (message) //get the message  	{	case WM_CREATE:		SetTimer(hwnd, ID_TIMER, 1000, TimerProc);		return 0;	case WM_DESTROY:		KillTimer(hwnd, ID_TIMER);		PostQuitMessage(0);		return 0;	}	return  DefWindowProc(hwnd, message, wParam, lParam);}VOID	CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime){	static BOOL	fFlipFlop = FALSE;	HBRUSH		hBrush;	HDC         hdc;	RECT        rc;	MessageBeep(-1);	fFlipFlop = !fFlipFlop;	GetClientRect(hwnd, &rc);	hdc = GetDC(hwnd);	hBrush = CreateSolidBrush(fFlipFlop ? RGB(255, 0, 0) : RGB(0, 0, 255));	FillRect(hdc, &rc, hBrush);	ReleaseDC(hwnd, hdc);	DeleteObject(hBrush);}



8.2.3 方法三

iTimerID = SetTimer(NULL, 0, wMsecInterval, TimerProc);

如果返回0 ,表示没有可调的定时器。


KillTimer(NULL, iTimerID);


8.3 使用计时器作为时钟

8.3.1 数字时钟

#include <windows.h>  #define ID_TIMER 1LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,	PSTR szCmdLine, int iCmdShow){	static      TCHAR szAppName[] = TEXT("DigClock");	HWND        hwnd;	MSG         msg;	WNDCLASS    wndClass;       //The window Class  	wndClass.style = CS_HREDRAW | CS_VREDRAW;	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.  	wndClass.cbClsExtra = 0;	wndClass.cbWndExtra = 0;	wndClass.hInstance = hInstance;	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);	wndClass.lpszMenuName = NULL;	wndClass.lpszClassName = szAppName;	//Register the Window Class to the Windows System.   	if (!RegisterClass(&wndClass))	{		MessageBox(NULL, TEXT("This program require Windows NT!"),			szAppName, MB_ICONERROR);		return 0;	}	//This function will generate an WM_CREATE message.  	hwnd = CreateWindow(szAppName,      //Window class name  		TEXT("Digital Clock"),      //Window caption  		WS_OVERLAPPEDWINDOW,            //Window Style  		CW_USEDEFAULT,                  //initial x position  		CW_USEDEFAULT,                  //initial y position  		CW_USEDEFAULT,                  //initial x size  		CW_USEDEFAULT,                  //initial y size  		NULL,                           //parent window handle  		NULL,                           //window menu handle  		hInstance,                      //program instance handle  		NULL);                          //creation parameters  	ShowWindow(hwnd, iCmdShow);	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.  						/* The message loop for this program.						if received the WM_QUIT message, the function will return 0.*/	while (GetMessage(&msg, NULL, 0, 0))	{		TranslateMessage(&msg);		DispatchMessage(&msg);	}	return msg.wParam;}void DisplayDigit(HDC hdc, int iNumber){	static BOOL  fSevenSegment[10][7] = {		1, 1, 1, 0, 1, 1, 1,     // 0		0, 0, 1, 0, 0, 1, 0,     // 1		1, 0, 1, 1, 1, 0, 1,     // 2		1, 0, 1, 1, 0, 1, 1,     // 3		0, 1, 1, 1, 0, 1, 0,     // 4		1, 1, 0, 1, 0, 1, 1,     // 5		1, 1, 0, 1, 1, 1, 1,     // 6		1, 0, 1, 0, 0, 1, 0,     // 7		1, 1, 1, 1, 1, 1, 1,     // 8		1, 1, 1, 1, 0, 1, 1 };  // 9	static POINT ptSegment[7][6] = {		 7,  6,  11,  2,  31,  2,  35,  6,  31, 10,  11, 10,		 6,  7,  10, 11,  10, 31,   6, 35,   2, 31,   2, 11,		36,  7,  40, 11,  40, 31,  36, 35,  32, 31,  32, 11,		 7, 36,  11, 32,  31, 32,  35, 36,  31, 40,  11, 40,		 6, 37,  10, 41,  10, 61,   6, 65,   2, 61,   2, 41,		36, 37,  40, 41,  40, 61,  36, 65,  32, 61,  32, 41,		 7, 66,  11, 62,  31, 62,  35, 66,  31, 70,  11, 70 };	int iSeg;	for (iSeg = 0; iSeg < 7; iSeg++)		if (fSevenSegment[iNumber][iSeg])			Polygon(hdc, ptSegment[iSeg], 6);}void DisplayTwoDigits(HDC hdc, int iNumber, BOOL fSuppress){	if (!fSuppress || (iNumber / 10 != 0))		DisplayDigit(hdc, iNumber / 10);	OffsetWindowOrgEx(hdc, -42, 0, NULL);	DisplayDigit(hdc, iNumber % 10);	OffsetWindowOrgEx(hdc, -42, 0, NULL);}void DisplayColon(HDC hdc){	POINT ptColon[2][4] = { 2,  21,  6,  17,  10, 21,  6, 25,							2,  51,  6,  47,  10, 51,  6, 55 };	Polygon(hdc, ptColon[0], 4);	Polygon(hdc, ptColon[1], 4);	OffsetWindowOrgEx(hdc, -12, 0, NULL);}void DisplayTime(HDC hdc, BOOL f24Hour, BOOL fSuppress){	SYSTEMTIME st;	GetLocalTime(&st);	if (f24Hour)		DisplayTwoDigits(hdc, st.wHour, fSuppress);	else		DisplayTwoDigits(hdc, (st.wHour %= 12) ? st.wHour : 12, fSuppress);	DisplayColon(hdc);	DisplayTwoDigits(hdc, st.wMinute, FALSE);	DisplayColon(hdc);	DisplayTwoDigits(hdc, st.wSecond, FALSE);}//define the Window Procedure WndProc  LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){	static BOOL		f24Hour, fSuppress;	static HBRUSH	hBrushRed;	static int		cxClient, cyClient;	HDC				hdc;	PAINTSTRUCT		ps;	TCHAR			szBuffer[2];	switch (message) //get the message  	{	case WM_CREATE:		hBrushRed = CreateSolidBrush(RGB(255, 0, 0));		SetTimer(hwnd, ID_TIMER, 1000, NULL);				//fall through	case WM_SETTINGCHANGE:		GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, szBuffer, 2);		f24Hour = (szBuffer[0] == TEXT('1'));		GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITLZERO, szBuffer, 2);		fSuppress = (szBuffer[0] == TEXT('0'));		InvalidateRect(hwnd, NULL, TRUE);		return 0;	case WM_SIZE:		cxClient = LOWORD(lParam);		cyClient = HIWORD(lParam);		return 0;	case WM_TIMER:		InvalidateRect(hwnd, NULL, TRUE);		return 0;	case WM_PAINT:		hdc = BeginPaint(hwnd, &ps);		SetMapMode(hdc, MM_ISOTROPIC);		SetWindowExtEx(hdc, 276, 72, NULL); //Set the logical point of the current windows		SetViewportExtEx(hdc, cxClient, cyClient, NULL);	//Map the logical position to the device position		SetWindowOrgEx(hdc, 138, 36, NULL);	//Set the logical org position		SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);	//Set the device org position		SelectObject(hdc, GetStockObject(NULL_PEN));		SelectObject(hdc, hBrushRed);		DisplayTime(hdc, f24Hour, fSuppress);		EndPaint(hwnd, &ps);		return 0;	case WM_DESTROY:		KillTimer(hwnd, ID_TIMER);		DeleteObject(hBrushRed);		PostQuitMessage(0);		return 0;	}	return  DefWindowProc(hwnd, message, wParam, lParam);}


8.3.2  获取当前时间

typedef struct _SYSTEMTIME {    WORD wYear;    WORD wMonth;    WORD wDayOfWeek;    WORD wDay;    WORD wHour;    WORD wMinute;    WORD wSecond;    WORD wMilliseconds;} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;

SYSTEMTIME   GetLocalTime  和GetSystemTime

SetLocalTime

SetSystemTime


8.3.3 显示数字与冒号

8.3.4 考虑国际化

GetDateFormat

GetTimeFormat  格式化日期和时间


如果时钟每分钟才变化一次 需要处理WM_TIMECHANGE消息


8.3.5 模拟时钟

#include <windows.h>#include <math.h>#define ID_TIMER	1#define TWOPI		(2 * 3.14159)LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,	PSTR szCmdLine, int iCmdShow){	static      TCHAR szAppName[] = TEXT("Clock");	HWND        hwnd;	MSG         msg;	WNDCLASS    wndClass;       //The window Class  	wndClass.style = CS_HREDRAW | CS_VREDRAW;	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.  	wndClass.cbClsExtra = 0;	wndClass.cbWndExtra = 0;	wndClass.hInstance = hInstance;	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);	wndClass.lpszMenuName = NULL;	wndClass.lpszClassName = szAppName;	//Register the Window Class to the Windows System.   	if (!RegisterClass(&wndClass))	{		MessageBox(NULL, TEXT("This program require Windows NT!"),			szAppName, MB_ICONERROR);		return 0;	}	//This function will generate an WM_CREATE message.  	hwnd = CreateWindow(szAppName,      //Window class name  		TEXT("Analog Clock"),      //Window caption  		WS_OVERLAPPEDWINDOW,            //Window Style  		CW_USEDEFAULT,                  //initial x position  		CW_USEDEFAULT,                  //initial y position  		CW_USEDEFAULT,                  //initial x size  		CW_USEDEFAULT,                  //initial y size  		NULL,                           //parent window handle  		NULL,                           //window menu handle  		hInstance,                      //program instance handle  		NULL);                          //creation parameters  	ShowWindow(hwnd, iCmdShow);	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.  						/* The message loop for this program.						if received the WM_QUIT message, the function will return 0.*/	while (GetMessage(&msg, NULL, 0, 0))	{		TranslateMessage(&msg);		DispatchMessage(&msg);	}	return msg.wParam;}void SetIsotropic(HDC hdc, int cxClient, int cyClient){	SetMapMode(hdc, MM_ISOTROPIC);	SetWindowExtEx(hdc, 1000, 1000, NULL);	SetViewportExtEx(hdc, cxClient / 2, -cyClient / 2, NULL);	SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);}void RotatePoint(POINT pt[], int iNum, int iAngle){	int		i;	POINT	ptTemp;	for (i = 0; i < iNum; i++)	{		ptTemp.x = (int)(pt[i].x * cos(TWOPI * iAngle / 360) +			pt[i].y * sin(TWOPI * iAngle / 360));		ptTemp.y = (int)(pt[i].y * cos(TWOPI * iAngle / 360) +			pt[i].x * sin(TWOPI * iAngle / 360));		pt[i] = ptTemp;	}}void DrawClock(HDC hdc){	int		iAngle;	POINT	pt[3];	for (iAngle = 0; iAngle < 360; iAngle += 6)	{		pt[0].x = 0;		pt[0].y = 900;		RotatePoint(pt, 1, iAngle);		pt[2].x = pt[2].y = iAngle % 5 ? 33 : 100;		pt[0].x -= pt[2].x / 2;		pt[0].y -= pt[2].y / 2;		pt[1].x = pt[0].x + pt[2].x;		pt[1].y = pt[0].y + pt[2].y;		SelectObject(hdc, GetStockObject(BLACK_BRUSH));		Ellipse(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);	}}void DrawHands(HDC hdc, SYSTEMTIME * pst, BOOL fChange){	static POINT	pt[3][5] = { 0, -150, 100, 0, 0, 600, -100, 0, 0, -150,								 0, -200,  50, 0, 0, 800,  -50, 0, 0, -200,								 0,    0,   0, 0, 0,   0,    0, 0, 0,  800 };	int				i, iAngle[3];	POINT			ptTemp[3][5];	iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute / 2;	iAngle[1] = pst->wMinute * 6;	iAngle[2] = pst->wSecond * 6;	memcpy(ptTemp, pt, sizeof(pt));	for (i = fChange ? 0 : 2; i < 3; i++)	{		RotatePoint(ptTemp[i], 5, iAngle[i]);		Polyline(hdc, ptTemp[i], 5);	}}//define the Window Procedure WndProc  LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){	static int			cxClient, cyClient;	static SYSTEMTIME	stPrevious;	BOOL				fChange;	HDC					hdc;	PAINTSTRUCT			ps;	SYSTEMTIME			st;	switch (message) //get the message  	{	case WM_CREATE:		SetTimer(hwnd, ID_TIMER, 1000, NULL);		GetLocalTime(&st);		stPrevious = st;		return 0;	case WM_SIZE:		cxClient = LOWORD(lParam);		cyClient = HIWORD(lParam);		return 0;	case WM_TIMER:		GetLocalTime(&st);		fChange = (st.wHour != stPrevious.wHour) ||			(st.wMinute != stPrevious.wMinute);		hdc = GetDC(hwnd);		SetIsotropic(hdc, cxClient, cyClient);		SelectObject(hdc, GetStockObject(WHITE_PEN));		DrawHands(hdc, &stPrevious, fChange);		SelectObject(hdc, GetStockObject(BLACK_PEN));		DrawHands(hdc, &st, TRUE);		ReleaseDC(hwnd, hdc);		stPrevious = st;		return 0;	case WM_PAINT:		hdc = BeginPaint(hwnd, &ps);		SetIsotropic(hdc, cxClient, cyClient);		DrawClock(hdc);		DrawHands(hdc, &stPrevious, TRUE);		EndPaint(hwnd, &ps);		return 0;	case WM_DESTROY:		KillTimer(hwnd, ID_TIMER);		PostQuitMessage(0);		return 0;	}	return  DefWindowProc(hwnd, message, wParam, lParam);}

坐标相对原点旋转的计算公式




8.4 在状态报告上使用计时器

whatclr程序

#include <windows.h>#define ID_TIMER	1void FindWindowSize(int *, int *);LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,	PSTR szCmdLine, int iCmdShow){	static      TCHAR szAppName[] = TEXT("WhatCtr");	HWND        hwnd;	int			cxWindow, cyWindow;	MSG         msg;	WNDCLASS    wndClass;       //The window Class  	wndClass.style = CS_HREDRAW | CS_VREDRAW;	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.  	wndClass.cbClsExtra = 0;	wndClass.cbWndExtra = 0;	wndClass.hInstance = hInstance;	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);	wndClass.lpszMenuName = NULL;	wndClass.lpszClassName = szAppName;	//Register the Window Class to the Windows System.   	if (!RegisterClass(&wndClass))	{		MessageBox(NULL, TEXT("This program require Windows NT!"),			szAppName, MB_ICONERROR);		return 0;	}	FindWindowSize(&cxWindow, &cyWindow);	//This function will generate an WM_CREATE message.  	hwnd = CreateWindow(szAppName,      //Window class name  		TEXT("What Color"),      //Window caption  		WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_BORDER,            //Window Style  		CW_USEDEFAULT,                  //initial x position  		CW_USEDEFAULT,                  //initial y position  		cxWindow,                  //initial x size  		cyWindow,                  //initial y size  		NULL,                           //parent window handle  		NULL,                           //window menu handle  		hInstance,                      //program instance handle  		NULL);                          //creation parameters  	ShowWindow(hwnd, iCmdShow);	UpdateWindow(hwnd); //This function will generate a WM_PAINT message.  						/* The message loop for this program.						if received the WM_QUIT message, the function will return 0.*/	while (GetMessage(&msg, NULL, 0, 0))	{		TranslateMessage(&msg);		DispatchMessage(&msg);	}	return msg.wParam;}void FindWindowSize(int * pcxWindow, int * pcyWindow){	HDC			hdcScreen;	TEXTMETRIC	tm;	hdcScreen = CreateIC(TEXT("DISPLAY"), NULL, NULL, NULL);	GetTextMetrics(hdcScreen, &tm);	DeleteDC(hdcScreen);	*pcxWindow = 2 * GetSystemMetrics(SM_CXBORDER) +						12 * tm.tmAveCharWidth;	*pcyWindow = 2 * GetSystemMetrics(SM_CYBORDER) +					 GetSystemMetrics(SM_CYCAPTION) +						2 * tm.tmHeight;}//define the Window Procedure WndProc  LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){	static COLORREF	cr, crLast;	static HDC		hdcScreen;	HDC				hdc;	PAINTSTRUCT		ps;	POINT			pt;	RECT			rc;	TCHAR			szBuffer[16];	switch (message) //get the message  	{	case WM_CREATE:		hdcScreen = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);		SetTimer(hwnd, ID_TIMER, 100, NULL);		return 0;	case WM_TIMER:		GetCursorPos(&pt);		cr = GetPixel(hdcScreen, pt.x, pt.y);		//SetPixel(hdcScreen, pt.x, pt.y, 0);		if (cr != crLast)		{			crLast = cr;			InvalidateRect(hwnd, NULL, FALSE);		}		return 0;	case WM_PAINT:		hdc = BeginPaint(hwnd, &ps);		GetClientRect(hwnd, &rc);		wsprintf(szBuffer, TEXT("  %02X %02X %02X  "),				GetRValue(cr), GetGValue(cr), GetBValue(cr));		DrawText(hdc, szBuffer, -1, &rc,				DT_SINGLELINE | DT_CENTER | DT_VCENTER);		EndPaint(hwnd, &ps);		return 0;	case WM_DESTROY:		DeleteDC(hdcScreen);		KillTimer(hwnd, ID_TIMER);		PostQuitMessage(0);		return 0;	}	return  DefWindowProc(hwnd, message, wParam, lParam);}
获得屏幕上当前鼠标位置的RGB颜色的16进制值



上一篇:《Windows程序设计》读书笔九 子窗口控件
下一篇:一道关于链表的基本操作题

发表评论

最新留言

感谢大佬
[***.8.128.20]2025年04月02日 04时07分57秒