windows程序设计中的一个小程序,大家给点解释!!!

yiruirui0507 2010-12-25 12:15:24
#include <windows.h>

struct
{
int iStyle ;
TCHAR * szText ;
}
button[] =
{
BS_PUSHBUTTON, TEXT ("PUSHBUTTON"),
BS_DEFPUSHBUTTON, TEXT ("DEFPUSHBUTTON"),
BS_CHECKBOX, TEXT ("CHECKBOX"),
BS_AUTOCHECKBOX, TEXT ("AUTOCHECKBOX"),
BS_RADIOBUTTON, TEXT ("RADIOBUTTON"),
BS_3STATE, TEXT ("3STATE"),
BS_AUTO3STATE, TEXT ("AUTO3STATE"),
BS_GROUPBOX, TEXT ("GROUPBOX"),
BS_AUTORADIOBUTTON, TEXT ("AUTORADIO"),
BS_OWNERDRAW, TEXT ("OWNERDRAW")
} ;

#define NUM (sizeof button / sizeof button[0])

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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("BtnLook") ;
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 ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}

hwnd = CreateWindow (szAppName, TEXT ("Button Look"),
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 hwndButton[NUM] ;
static RECT rect ;
static TCHAR szTop[] = TEXT ("message wParam lParam"),
szUnd[] = TEXT ("_______ ______ ______"),
szFormat[] = TEXT ("%-16s%04X-%04X %04X-%04X"),
szBuffer[50] ;
static int cxChar, cyChar ;
HDC hdc ;
PAINTSTRUCT ps ;
int i ;

switch (message)
{
case WM_CREATE :
cxChar = LOWORD (GetDialogBaseUnits ()) ;
cyChar = HIWORD (GetDialogBaseUnits ()) ;

for (i = 0 ; i < NUM ; i++)
hwndButton[i] = CreateWindow ( TEXT("button"),
button[i].szText,
WS_CHILD | WS_VISIBLE | button[i].iStyle,
cxChar, cyChar * (1 + 2 * i),
20 * cxChar, 7 * cyChar / 4,
hwnd, (HMENU) i,
(HINSTANCE)GetWindowLong(hwndButton[i],GWL_HINSTANCE), NULL) ;

//((LPCREATESTRUCT) lParam)->hInstance, NULL) ;
return 0 ;

case WM_SIZE :
rect.left = 24 * cxChar ;
rect.top = 2 * cyChar ;
rect.right = LOWORD (lParam) ;
rect.bottom = HIWORD (lParam) ;
return 0 ;

case WM_PAINT :
InvalidateRect (hwnd, &rect, TRUE) ;

hdc = BeginPaint (hwnd, &ps) ;
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
SetBkMode (hdc, TRANSPARENT) ;

TextOut (hdc, 24 * cxChar, cyChar, szTop, lstrlen (szTop)) ;
TextOut (hdc, 24 * cxChar, cyChar, szUnd, lstrlen (szUnd)) ;

EndPaint (hwnd, &ps) ;
return 0 ;

case WM_DRAWITEM :
case WM_COMMAND :
ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ;

hdc = GetDC (hwnd) ;
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1),
szBuffer,
wsprintf (szBuffer, szFormat,
message == WM_DRAWITEM ? TEXT ("WM_DRAWITEM") :
TEXT ("WM_COMMAND"),
HIWORD (wParam), LOWORD (wParam),
HIWORD (lParam), LOWORD (lParam))) ;

ReleaseDC (hwnd, hdc) ;
ValidateRect (hwnd, &rect) ;
break ;
case WM_LBUTTONDOWN:
MessageBox(hwnd,TEXT("ABC"),TEXT("XX"),MB_OK);
return 0;

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

以上代码是子窗口控件那章的第一个例子,我加了一个WM_LBUTTONDOWN消息处理,关于这个程序我有点疑问:
1 这些标准控件是如何创建的?应该是根据类名创建的吧,难道这里的CreateWindow ( TEXT("button"), button就是标准的类名吗?系统自己创建的窗口类?应该是这样吧,不然创建不出来控件的。
2 这些标准控件会自动响应WM_COMMOND消息?那为什么我加了WM_LBUTTONDOWN他们就不响应呢?10个窗口只有一个GROUP控件会响应,其他都没反应的,求给这里一些合理的解释,谢谢。或者提供一些资料让我晓得原理也OK。
...全文
216 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiruirui0507 2010-12-27
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 wltg2001 的回复:]
这个是针对所有的CREATEWINDOW还是子窗口的CREATEWINDOW?
为什么父窗口的
hwnd = CreateWindow (szAppName, TEXT ("Button Look"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NUL……
[/Quote]

OK,晓得了。3Q!
wltg2001 2010-12-26
  • 打赏
  • 举报
回复
这个是针对所有的CREATEWINDOW还是子窗口的CREATEWINDOW?
为什么父窗口的
hwnd = CreateWindow (szAppName, TEXT ("Button Look"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
就需要HINSTANCE呢?这个HINSTANCE不就是一个标识码?应该是必须要的吧?
================
当然是针对所有的了,至于HINSTANCE是不是应该要,MSDN才是权威啊!上面不是贴过MSDN上对这个参数解释了吗?
hInstance
[in] Windows 95/98/Me: Handle to the instance of the module to be associated with the window.
Windows NT/2000/XP: This value is ignored.

yiruirui0507 2010-12-26
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 wltg2001 的回复:]
一方面我的CreateWindow在MSDN上没这个说明的,另外,这个CreateWindow的HINSTANCE跟GETWINDOWLONG的HINSTANCE一样吗?这咋么解释?
===================
你没有看明白我上面说的,
你上面的hwndButton[i] = CreateWindow ( TEXT("button"),
button[i].szText,……
[/Quote]
这个是针对所有的CREATEWINDOW还是子窗口的CREATEWINDOW?
为什么父窗口的
hwnd = CreateWindow (szAppName, TEXT ("Button Look"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
就需要HINSTANCE呢?这个HINSTANCE不就是一个标识码?应该是必须要的吧?
wltg2001 2010-12-26
  • 打赏
  • 举报
回复
一方面我的CreateWindow在MSDN上没这个说明的,另外,这个CreateWindow的HINSTANCE跟GETWINDOWLONG的HINSTANCE一样吗?这咋么解释?
===================
你没有看明白我上面说的,
你上面的hwndButton[i] = CreateWindow ( TEXT("button"),
button[i].szText,
WS_CHILD | WS_VISIBLE | button[i].iStyle,
cxChar, cyChar * (1 + 2 * i),
20 * cxChar, 7 * cyChar / 4,
hwnd, (HMENU) i,
(HINSTANCE)GetWindowLong(hwndButton[i],GWL_HINSTANCE), NULL)
中的(HINSTANCE)GetWindowLong(hwndButton[i],GWL_HINSTANCE)这句因为hwndButton[i]里面的句柄值是错误的,所以GetWindowLong根本就没有成功。
但是CreateWindow却没有因为上面GetWindowLong的失败而失败,因为CreateWindow中的这个参数在NT/XP下是忽略的。
yiruirui0507 2010-12-26
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 wltg2001 的回复:]
引用 10 楼 yiruirui0507 的回复:
引用 8 楼 wltg2001 的回复:
引用 7 楼 yiruirui0507 的回复:
又发现了一个新问题:
在WM_CREATE消息处理过程中,我是这样写的获取实例句柄:

C/C++ code
(HINSTANCE)GetWindowLong(hwndButton[i],GWL_HINSTANCE), NULL) ;

……
[/Quote]
一方面我的CreateWindow在MSDN上没这个说明的,另外,这个CreateWindow的HINSTANCE跟GETWINDOWLONG的HINSTANCE一样吗?这咋么解释?
wltg2001 2010-12-26
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 yiruirui0507 的回复:]
引用 8 楼 wltg2001 的回复:
引用 7 楼 yiruirui0507 的回复:
又发现了一个新问题:
在WM_CREATE消息处理过程中,我是这样写的获取实例句柄:

C/C++ code
(HINSTANCE)GetWindowLong(hwndButton[i],GWL_HINSTANCE), NULL) ;


这样写程序能够正常运行的,问题是:这里的hwndB……
[/Quote]
是MSDN上的说明啊,不过不是GetWindowLong的说明,而是CreateWindow的说明。
yiruirui0507 2010-12-26
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 wltg2001 的回复:]
引用 7 楼 yiruirui0507 的回复:
又发现了一个新问题:
在WM_CREATE消息处理过程中,我是这样写的获取实例句柄:

C/C++ code
(HINSTANCE)GetWindowLong(hwndButton[i],GWL_HINSTANCE), NULL) ;


这样写程序能够正常运行的,问题是:这里的hwndButton[i]还没值吧?这样也行?不行但没……
[/Quote]
对了,你这个是GETWINDOWLONG在MSDN上的说明吗?为什么我的MSDN上没这句话呢?奇怪了。。。。
yiruirui0507 2010-12-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 superarhow 的回复:]
>>1 这些标准控件是如何创建的?应该是根据类名创建的吧,难道这里的CreateWindow ( TEXT("button"), button就是标准的类名吗?系统自己创建的窗口类?应该是这样吧,不然创建不出来控件的。

是这样的

>>2 这些标准控件会自动响应WM_COMMOND消息?那为什么我加了WM_LBUTTONDOWN他们就不响应呢?10个窗口只有一个GROUP控件会响应,其他……
[/Quote]

查了一些资料咋么消息反射都是关于MFC的,那个看不太懂,有WINDOWS SDK方面的吗、
superarhow 2010-12-25
  • 打赏
  • 举报
回复
>>1 这些标准控件是如何创建的?应该是根据类名创建的吧,难道这里的CreateWindow ( TEXT("button"), button就是标准的类名吗?系统自己创建的窗口类?应该是这样吧,不然创建不出来控件的。

是这样的

>>2 这些标准控件会自动响应WM_COMMOND消息?那为什么我加了WM_LBUTTONDOWN他们就不响应呢?10个窗口只有一个GROUP控件会响应,其他都没反应的,求给这里一些合理的解释,谢谢。或者提供一些资料让我晓得原理也OK。

这个涉及消息反射的一些东东.google一下消息反射.
zjfhgdx 2010-12-25
  • 打赏
  • 举报
回复
button就系统的类名
wltg2001 2010-12-25
  • 打赏
  • 举报
回复
父窗口的HISNTANCE跟子窗口的HINSTANCE有关系没?
===============
HINSTANCE是相对于进程来说的,所以父窗口和子窗口的HINSTANCE是一样的。
wltg2001 2010-12-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 yiruirui0507 的回复:]
又发现了一个新问题:
在WM_CREATE消息处理过程中,我是这样写的获取实例句柄:

C/C++ code
(HINSTANCE)GetWindowLong(hwndButton[i],GWL_HINSTANCE), NULL) ;


这样写程序能够正常运行的,问题是:这里的hwndButton[i]还没值吧?这样也行?不行但没报错。
求解释!!!!!换成hwnd父窗口的句柄倒……
[/Quote]
能正常执行的原因很简单,MSDN上写得很清楚:
hInstance
[in] Windows 95/98/Me: Handle to the instance of the module to be associated with the window.
Windows NT/2000/XP: This value is ignored.
==========
简单地说,对NT或是XP之类的系统,这个参数是无效的,写NULL都行。
yiruirui0507 2010-12-25
  • 打赏
  • 举报
回复
又发现了一个新问题:
在WM_CREATE消息处理过程中,我是这样写的获取实例句柄:
(HINSTANCE)GetWindowLong(hwndButton[i],GWL_HINSTANCE), NULL) ;

这样写程序能够正常运行的,问题是:这里的hwndButton[i]还没值吧?这样也行?不行但没报错。
求解释!!!!!换成hwnd父窗口的句柄倒是可以,请给说一下这个实例句柄到底是个什么东西?
父窗口创建的时候不是有一个HINSTANCE了吗?子窗口也需要HINSTANCE干嘛?父窗口的HISNTANCE跟子窗口的HINSTANCE有关系没?迷迷糊糊很久了,今天在此把问题提出来,分数绝不是问题。
yiruirui0507 2010-12-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 matrixcl 的回复:]
引用 2 楼 superarhow 的回复:
>>1 这些标准控件是如何创建的?应该是根据类名创建的吧,难道这里的CreateWindow ( TEXT("button"), button就是标准的类名吗?系统自己创建的窗口类?应该是这样吧,不然创建不出来控件的。

是这样的

>>2 这些标准控件会自动响应WM_COMMOND消息?那为什么我加了WM_LBUTTONDOWN他们就不响应……
[/Quote]

恩,解释的是对的,另外我最后那个问题也有点眉目了,我把WM_DRAWITEM消息注释掉,对话框的标题就改不掉了,其原因应该是第10个子窗口的BS_OWNERDRAW风格所导致的吧,它会自动给父窗口触发WM_DRAWITEM消息????调试结果证明是真的,区区设置一个风格就能触发一个消息???真的假的???
matrixcl 2010-12-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 superarhow 的回复:]
>>1 这些标准控件是如何创建的?应该是根据类名创建的吧,难道这里的CreateWindow ( TEXT("button"), button就是标准的类名吗?系统自己创建的窗口类?应该是这样吧,不然创建不出来控件的。

是这样的

>>2 这些标准控件会自动响应WM_COMMOND消息?那为什么我加了WM_LBUTTONDOWN他们就不响应呢?10个窗口只有一个GROUP控件会响应,其他都没反应的,求给这里一些合理的解释,谢谢。或者提供一些资料让我晓得原理也OK。

这个涉及消息反射的一些东东.google一下消息反射.[/Quote]

1.正确

2.响应WM_LBUTTONDOWN应该在Button自己的消息循环中,而不是Dialog的消息循环来响应。
button自己的消息循环实现了,在收到一次WM_LBUTTONDOWN+WM_LBUTTONUP之后,给它的父窗口也就是dialog发一个WM_COMMAND.

至于Group控件,这个比较特殊。group中间的空闲还是属于对话框的,所以在其中点击触发WM_LBUTTONDOWN就合情合理了
yiruirui0507 2010-12-25
  • 打赏
  • 举报
回复
case WM_DRAWITEM :
case WM_COMMAND :
ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ;

hdc = GetDC (hwnd) ;
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1),
szBuffer,
wsprintf (szBuffer, szFormat,
message == WM_DRAWITEM ? TEXT ("WM_DRAWITEM") :
TEXT ("WM_COMMAND"),
HIWORD (wParam), LOWORD (wParam),
HIWORD (lParam), LOWORD (lParam))) ;

//SendMessage((HWND)lParam,BM_SETSTATE,1,0);
//SendMessage((HWND)lParam,BM_SETCHECK,(WPARAM)!SendMessage((HWND)lParam,BM_GETCHECK,0,0),0);
//SendMessage((HWND)lParam,BM_SETCHECK,1,0);
SetWindowText(hwnd,TEXT("AABB"));
SetWindowText((HWND)lParam,TEXT("xxx"));
ReleaseDC (hwnd, hdc) ;
ValidateRect (hwnd, &rect) ;
break ;

为什么我在这个消息处理程序中调用SetWindowText也能把父窗口的标题给改掉呢?书上说WM_COMMAND消息是单击子窗口的时候才给父窗口发送这个消息啊,没单击为什么也可以?莫非。。。。。。。
麻烦大侠给解释一下,困扰的不行。3Q先!

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧