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。
...全文
215 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先!
Windows 10或Windows 11操作系统,用户经常会遇到共享打印机时出现的一系列错误代码,这些错误代码可能会阻碍打印机共享功能的正常使用。常见的错误代码包括0x00000057、0x00000709和0x0000011b,这些代码通常指出了不同的问题,比如权限不足、服务未运行或配置错误等。除此之外,还有一些故障提示如“连接失败”或“内存不足”,这些都可能影响到打印机共享的稳定性。 要解决这些故障,首先要确保打印机已经正确地连接到网络,并且在需要共享的电脑上进行了设置。确保打印机驱动程序是最新的,并且在共享设置没有错误配置。对于权限问题,需要检查网络上的用户账户是否具有足够的权限来访问共享打印机。同时,也要确保打印机服务正在运行,特别是“Print Spooler”服务,因为这是打印机共享服务的核心组件。 在某些情况下,问题可能与操作系统的更新有关,如升级到最新版的Windows 10或Windows 11后可能出现的兼容性问题。这时,可能需要查看微软的官方支持文档来获取特定的解决方案或更新。 对于错误代码0x00000057,这通常是由于没有足够的权限来访问网络打印机或其共享资源,解决方法是确保网络打印机的权限设置正确,包括在组策略设置相应的访问权限。而0x00000709错误可能是由于打印机驱动问题或打印机端口配置错误,可以尝试重新安装或更新打印机驱动来解决。至于0x0000011b错误,这往往是因为打印机队列服务的问题,检查并重启“Print Spooler”服务通常是解决这类问题的常见手段。 至于“连接失败”或“内存不足”这类故障,通常与客户端和打印机之间的网络连接以及打印机本地资源的使用情况有关。检查网络连接,确保打印机所在的网络段没有故障或断。同时,如果打印机的打印队列长时间得不到处理,可能会导致内存不足的情况,这时可能需要清理打印队列或增加打印机的内存配置。 为了帮助用户更快速地解决这些问题,市面上出现了各种打印机共享错误修复工具。这些工具往往通过预设的修复程序来自动检测和修正打印机共享常见的问题。它们可以快速检查打印机驱动、网络连接以及共享设置,并且能够提供一键修复功能,大幅减少了用户自行排查和解决问题的难度。 然而,在使用这些修复工具之前,用户应确保这些工具的来源是安全可靠的,避免因使用不当的修复工具而引发其他系统安全或隐私问题。用户可以到官方平台或者信誉良好的软件提供商处下载这些工具。通过细心检查打印机的共享设置,及时更新驱动程序和服务,以及合理使用修复工具,大多数共享打印机的问题都可以得到有效的解决。

16,548

社区成员

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

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

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