对windows程序设计书中的第七章例子的理解!有点困惑。

yiruirui0507 yiruirui0507 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
/*-------------------------------------------------
CHECKER3.C -- Mouse Hit-Test Demo Program No. 3
(c) Charles Petzold, 1998
-------------------------------------------------*/

#include <windows.h>

#define DIVISIONS 5

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK ChildWndProc (HWND, UINT, WPARAM, LPARAM) ;

TCHAR szChildClass[] = TEXT ("Checker3_Child") ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Checker3") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;

wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
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 ;

if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}

wndclass.lpfnWndProc = ChildWndProc ;
wndclass.cbWndExtra = sizeof (long) ;
wndclass.hIcon = NULL ;
wndclass.lpszClassName = szChildClass ;

RegisterClass (&wndclass) ;

hwnd = CreateWindow (szAppName, TEXT ("Checker3 Mouse Hit-Test Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;

ShowWindow (hwnd, iCmdShow) ;
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 HWND hwndChild[DIVISIONS][DIVISIONS] ;
int cxBlock, cyBlock, x, y ;

switch (message)
{
case WM_CREATE :
for (x = 0 ; x < DIVISIONS ; x++)
for (y = 0 ; y < DIVISIONS ; y++)
hwndChild[x][y] = CreateWindow (szChildClass, NULL,
WS_CHILDWINDOW | WS_VISIBLE,
0, 0, 0, 0,
hwnd, (HMENU) (y << 8 | x),
(HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
NULL) ;
return 0 ;

case WM_SIZE :
cxBlock = LOWORD (lParam) / DIVISIONS ;
cyBlock = HIWORD (lParam) / DIVISIONS ;

for (x = 0 ; x < DIVISIONS ; x++)
for (y = 0 ; y < DIVISIONS ; y++)
MoveWindow (hwndChild[x][y],
x * cxBlock, y * cyBlock,
cxBlock, cyBlock, TRUE) ;
return 0 ;

case WM_LBUTTONDOWN :
MessageBeep (0) ;
return 0 ;

case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}

LRESULT CALLBACK ChildWndProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;

switch (message)
{
case WM_CREATE :
SetWindowLong (hwnd, 0, 0) ; // on/off flag
return 0 ;

case WM_LBUTTONDOWN :
SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0)) ;
InvalidateRect (hwnd, NULL, FALSE) ;
return 0 ;

case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;

GetClientRect (hwnd, &rect) ;
Rectangle (hdc, 0, 0, rect.right, rect.bottom) ;

if (GetWindowLong (hwnd, 0))
{
MoveToEx (hdc, 0, 0, NULL) ;
LineTo (hdc, rect.right, rect.bottom) ;
MoveToEx (hdc, 0, rect.bottom, NULL) ;
LineTo (hdc, rect.right, 0) ;
}

EndPaint (hwnd, &ps) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}

头一次遇到涉及到子窗口的问题,发现理解起来有困难。
RegisterClass注册了两个窗口类,关键的问题就在于子窗口跟父窗口的联系搞不明白。
父窗口的WM_CREATE中创建了25个子窗口且保留了对应的句柄,
问题1
hwndChild[x][y] = CreateWindow (szChildClass, NULL,
WS_CHILDWINDOW | WS_VISIBLE,
0, 0, 0, 0,
hwnd, (HMENU) (y << 8 | x),
(HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
NULL) ;
这句的理解,子窗口的风格必须加上WS_CHILDWINDOW|WS_VISIBLE吗?另外这里创建的25个子窗口咋么没大小?0,0,0,0 有点奇怪。(HMENU) (y << 8 | x)这个也不懂什么意思,没有涉及到菜单啊?
问题2
MoveWindow (hwndChild[x][y],
x * cxBlock, y * cyBlock,
cxBlock, cyBlock, TRUE) ;
当窗口尺寸发生变化时,移动子窗口到指定位置,并且重绘每个子窗口,但是在子窗口的消息处理中WM_PAINT
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;

GetClientRect (hwnd, &rect) ;
Rectangle (hdc, 0, 0, rect.right, rect.bottom) ;

if (GetWindowLong (hwnd, 0))
{
MoveToEx (hdc, 0, 0, NULL) ;
LineTo (hdc, rect.right, rect.bottom) ;
MoveToEx (hdc, 0, rect.bottom, NULL) ;
LineTo (hdc, rect.right, 0) ;
}

EndPaint (hwnd, &ps) ;
return 0 ;
}
并没有做什么工作嘛,只是重新画了一下客户区矩形,请问这里又该如何理解?如果把MOVEWINDOW的TRUE改成FALSE会发生什么?
最后问题:
SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0)) ;
GETWINDOWLONG(HWND,0)这里的0是HWNDFIRST吧,也就是说看看窗口是否是处在父窗口的上面或者顶层,进行异或操作刚好让他相反。最后刷新客户区?我这理解的对否?
...全文

相关推荐

Windows程序设计第七章

Windows程序设计第七章Windows程序设计第七章

shuaiwang_01

MFC Windows 程序设计[127]之菜单初体验(附源码)

MFC是微软公司提供的一个类库(class libraries),用以减少应用程序开发人员的工作量。其中包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。有很多初学MFC的小伙伴们都觉得MFC比较难学,看书吧,看了就忘了,网上的一些教程又是写的含糊不清,故而学习起来很吃力...... 故此,本专栏亲自研究,实践,由易到难,层层深入,将调试过程中所遭所遇进行详细讲解,注意事项进行一一列举,希望能够帮助到各位初学MFC的小伙伴,避免走弯路,费时费力。............

五一编程

windows程序设计 及配书源码

通过阅读和实践书中的例子,开发者可以逐步提升在Windows平台上的编程技能,从而更好地应对各种复杂的开发任务。

chenzq360

windows程序设计王艳萍 配书代码

王艳萍老师的《Windows程序设计》一书,无疑为初学者和有经验的开发者提供了深入理解这一领域的宝贵资源。这本书通常会包含一系列的实例代码,帮助读者更好地理解和应用所学知识。

sanbudetuzi

windows程序设计-王艳萍配书代码

总的来说,"windows程序设计-王艳萍配书代码"是一个宝贵的资源,它通过实际的代码示例,帮助读者深入理解Windows程序设计的各个方面。

mysticalbaby
评论 10
收藏 已收藏
分享
返回顶部
yiruirui0507
VC/MFC 16,550 成员 421,606 内容