`
hcmfys
  • 浏览: 357584 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

WM_COMMAND

阅读更多

WM_COMMAND & WM_SYSCOMMAND

                                      

对于菜单、加速键来说,点击后Windows会都会向它们所属的窗体发送WM_COMMAND消息。除了菜单、加速键,一些子窗体也会引发这些消息。例如对话框中的按钮或者工具栏中按钮(控件发通知消息给父窗体)。WM_COMMAND消息中有两个参数,wparam、lparam,定义如下:

       wParam 高两个字节 通知码

       wParam 低两字节 命令ID

       lParam 发送命令消息的子窗体句柄。

       对于菜单和加速键来说,lParam为0,只有控件此项才非0。命令ID也就是资源脚本中定义的菜单项的命令ID或者加速键的命令ID;菜单的通知码为0;加速键的通知码为1。

       对于Windows菜单中菜单项和加速键,点击后,Windows会向所属的窗体发送WM_SYSCOMMAND,而不是WM_COMMAND消息。注意,WINDOWS菜单是系统菜单,也就是在标题栏点击鼠标左键的时候弹出的菜单。我们可以捕获WM_CREATE消息,加入自己的操作:GetSysMenu获取系统菜单句柄,然后对系统菜单进行操作,并且捕获添加菜单项(根据菜单命令ID)ID对应的WM_SYSCOMMAND消息进行处理。修改系统默认的菜单行为。

例如:#define IDM_SELMENU 0x4444

else if ( uMsg == WM_CREATE)

       {

              HMENU hMenu = GetSystemMenu(hWnd,0);

              AppendMenu(hMenu,0,IDM_SELMENU,"Show Hello");

              return DefWindowProc(hWnd,uMsg,wParam,lParam);

       }

       else if ( uMsg == WM_SYSCOMMAND) //

       {           

              if ( wParam << 16 >> 16 == 0x4444 )

              {

                     MessageBox(NULL,"SysMenu:Show Hello MenuItem", "sysmenu info",MB_OK);

                     return 0;

              }

              return DefWindowProc(hWnd,uMsg,wParam,lParam);

       }

       对于WM_SYSCOMMAND中如果是系统菜单的消息,我们没哟修改的,必须要交给DefWindowProc来处理,并且将返回值返回给Windows,不然你会发现不能拖动窗体、改变大小、最大最小化操作等。因为你如果不交给DefWindowProc处理,相当于屏蔽了SC_RESTORE SC_MOVE SC_MAXIMIZE SC_MINIMIZE SC_CLOSE等等操作了。这些命令都是通过Windows投递WM_SYSCOMMAND 消息,在DefWindowProc中进行处理的。

 

----------------------------------------------------------------------------------------------------------

#include   <stdlib.h>  
  #include   <stdio.h>  
  void   main(   void   )  
  {  
        char   buffer[20];  
        int     i   =   3445;  
        long   l   =   -344115L;  
        unsigned   long   ul   =   1234567890UL;  
        _itoa(   i,   buffer,   10   );//转换成10进制  
        printf(   "String   of   integer   %d   (radix   10):   %s\n",   i,   buffer   );  
        _itoa(   i,   buffer,   16   );//转换成16进制  
        printf(   "String   of   integer   %d   (radix   16):   0x%s\n",   i,   buffer   );  
        _itoa(   i,   buffer,   2     );//转换成2进制    
        printf(   "String   of   integer   %d   (radix   2):   %s\n",   i,   buffer   );  
   
        _ltoa(   l,   buffer,   16   );//转换成16进制  
        printf(   "String   of   long   int   %ld   (radix   16):   0x%s\n",   l,    
                                                                                                          buffer   );  
   
        _ultoa(   ul,   buffer,   16   );  
        printf(   "String   of   unsigned   long   %lu   (radix   16):   0x%s\n",   ul,  
                                                                                                          buffer   );  
  }  
   
   
  Output  
   
  String   of   integer   3445   (radix   10):   3445  
  String   of   integer   3445   (radix   16):   0xd75  
  String   of   integer   3445   (radix   2):   110101110101  
  String   of   long   int   -344115   (radix   16):   0xfffabfcd  
  String   of   unsigned   long   1234567890   (radix   16):   0x499602d2  

-----------------------------------------------------------------------------------------------------------

 

 

问题起因: 
   
      
   
    // force the system to re-read the mapping into shared memory 
    
// so that future invocations of the application will see it 
   
//  without the user having to reboot the system 
  WritePrivateProfileStringW( NULL, NULL, NULL, L"appname.ini" ); 

    查了一下msdn中WritePrivateProfileStringW的原型如下:
   
WINBASEAPI BOOL WINAPI WritePrivateProfileStringW (
 LPCWSTR lpAppName,
 LPCWSTR lpKeyName,
 LPCWSTR lpString,
 LPCWSTR lpFileName )

    其中的每个参数的类型都为LPCWSTR,实际中获得的文件名都为CString,问题产生。

问题分析:

    LPCWSTR 是Unicode字符串指针,初始化时串有多大,申请空间就有多大,以后存贮若超过则出现无法预料的结果,这是它与CString的不同之处。而CString是一个串类,内存空间类会自动管理。LPCWSTR 初始化如下:
    
LPCWSTR Name=L"TestlpCwstr"
    
    由于LPCWSTR必须指向Unicode的字符串,问题的关键变成了Anis字符与Unicode字符之间的转换,不同编码间的转换,通过查找资料可知,可以ATL中转换宏可以用如下方法实现:
//方法一
CString str=_T("TestStr");
USES_CONVERSION;
LPWSTR pwStr
=new wchar_t[str.GetLength()+1];
wcscpy(pwStr,T2W((LPCTSTR)str));

// 方法二

CString str
=_T("TestStr");
USES_CONVERSION;
LPWCSTR pwcStr 
= A2CW((LPCSTR)str);

  MFC中CString和LPSTR是可以通用,其中A2CW表示(LPCSTR)  -> (LPCWSTR),USER_CONVERSION表示用来定义一些中间变量,在使用ATL的转换宏之前必须定义该语句。

    顺便也提一下,如果将LPCWSTR转换成CString,那就更加容易,在msdn中的CString类说明中提到了可以直接用LPCWSTR来构造CString,所以可以进行如下的转换代码:   

LPCWSTR pcwStr = L"TestpwcStr";
CString str(pcwStr);

问题总结:    
    在头文件<atlconv.h>中定义了ATL提供的所有转换宏,如:    

  A2CW       (LPCSTR)  -> (LPCWSTR)
  A2W        (LPCSTR)  
-> (LPWSTR)
  W2CA       (LPCWSTR) 
-> (LPCSTR)
  W2A        (LPCWSTR) 
-> (LPSTR)

     所有的宏如下表所示: 

A2BSTR OLE2A T2A W2A
A2COLE OLE2BSTR T2BSTR W2BSTR
A2CT OLE2CA T2CA W2CA
A2CW OLE2CT T2COLE W2COLE
A2OLE OLE2CW T2CW W2CT
A2T OLE2T T2OLE W2OLE
A2W OLE2W T2W W2T

上表中的宏函数,非常的有规律,每个字母都有确切的含义如下:

2 to 的发音和 2 一样,所以借用来表示“转换为、转换到”的含义。
A ANSI 字符串,也就是 MBCS。
W、OLE 宽字符串,也就是 UNICODE。
T 中间类型T。如果定义了 _UNICODE,则T表示W;如果定义了 _MBCS,则T表示A
C const 的缩写

    利用这些宏,可以快速的进行各种字符间的转换。使用前必须包含头文件,并且申明USER_CONVERSION;使用 ATL 转换宏,由于不用释放临时空间,所以使用起来非常方便。但是考虑到栈空间的尺寸(VC 默认2M),使用时要注意几点:

    1、只适合于进行短字符串的转换;
    2、不要试图在一个次数比较多的循环体内进行转换;
    3、不要试图对字符型文件内容进行转换,因为文件尺寸一般情况下是比较大的;
    4、对情况 2 和 3,要使用 MultiByteToWideChar() 和 WideCharToMultiByte(); 
CString str=_T("TestStr");
USES_CONVERSION;
LPWCSTR pwcStr = A2CW((LPCSTR)str);
=>LPWCSTR pwcStr = A2CW((LPCSTR)str.GetBuffer());

分享到:
评论

相关推荐

    WM_COMMAND user message macroWM_COMMAND用户消息宏(5KB)

    **WM_COMMAND用户消息宏详解** 在Windows编程中,`WM_COMMAND`消息是窗口处理程序接收的一个关键消息,它表示用户与窗口控件交互的结果。这个消息宏被广泛用于响应菜单项的选择、控件的单击以及其他用户界面事件。...

    wm_commands:流行的Windows程序的Wm_Command SendMessage常量

    WM_Command SendMessage常量,用于流行的应用程序通过从EXE和DLL文件中提取菜单资源,您通常可以发现常量,以通过语言自己自动化这些功能。 .rc文件是文本,类似于以下内容(来自“进程监视器”): CONTEXT_...

    button响应WM_LBUTTONUP消息

    在默认情况下,Button控件只响应如WM_LBUTTONDOWN(鼠标左键按下)和WM_COMMAND(按钮点击)等消息,但不直接处理WM_LBUTTONUP。然而,开发者可以通过自定义代码来扩展控件的功能,使其能够对WM_LBUTTONUP做出反应。...

    Visual Basic 6.0使用API函数PostMessage操作计算器

    - `Msg`:要发送的消息类型,通常是一个WM_常量,如WM_KEYDOWN或WM_COMMAND。 - `wParam`:与消息相关的附加信息,根据消息类型的不同,它可以代表按键代码或者命令ID。 - `lParam`:另一个与消息相关的参数,如...

    ON_COMMAND, ON_MESSAGE, ON_NOTIFY它们的区别

    `ON_COMMAND` 宏主要用于处理标准的 Windows 命令消息 (`WM_COMMAND`)。当用户通过菜单项或工具栏按钮等界面元素触发事件时,系统会发送 `WM_COMMAND` 消息到相应的窗口。该消息包含了触发事件的控件标识符以及其他...

    C#_SendMessage

    - **WM_SYSCOMMAND (0x112)**: 此消息与WM_COMMAND类似,但用于系统菜单命令,例如最大化或最小化窗口。 ##### 定时器消息 - **WM_TIMER (0x113)**: 当设置了定时器时,定时器到期后系统会发送此消息。 ##### 滚动...

    MFC 全面解读WM_NOTIFY

    与常规的消息如`WM_COMMAND`不同,`WM_NOTIFY`提供了更丰富的信息结构和更灵活的通信方式,使其成为处理复杂控件事件的理想选择。 #### WM_NOTIFY的触发场景 `WM_NOTIFY`通常在以下几种情况下被触发: 1. **控件...

    WTL中控件消息实现

    WM_COMMAND 消息处理宏有五种,分别是COMMAND_HANDLER_EX、COMMAND_ID_HANDLER_EX、COMMAND_CODE_HANDLER_EX、COMMAND_RANGE_HANDLER_EX和COMMAND_RANGE_CODE_HANDLER_EX。这些宏可以用来处理来自控件的通知消息。 ...

    c# 句柄类库 .net操作句柄

    为了测试句柄操作,这个程序可能会模拟用户交互,发送如`WM_PAINT`、`WM_COMMAND`等常见消息,以观察窗口或控件的行为。 总结来说,C#中的句柄操作主要涉及与Windows API的交互,包括查找和管理句柄,以及使用API...

    VC中的所有WM消息.zip_VC中wm函数_Windows编程_wm 常见消息_wm消息

    1. **WM_COMMAND**:当菜单项、按钮或控件发送命令时,此消息被发送。可以处理控件的通知代码,比如按钮点击。 2. **WM_TIMER**:定时器触发时发送,常用于实现间隔执行某任务。 3. **WM_MOUSEMOVE**:鼠标移动时...

    Visual Studio 2008写的SDK对话框程序

    // Dialog.cpp : 定义应用程序的入口点。... case WM_COMMAND: //基本控件消息处理 break; case WM_CLOSE: EndDialog(hDlg, LOWORD(wParam)); return TRUE; break; } return FALSE; }

    消息钩子代码实现

    本篇文章将深入探讨消息钩子的实现及其在拦截`WM_COMMAND`消息中的应用。 首先,我们需要理解什么是`WM_COMMAND`消息。`WM_COMMAND`是Windows消息的一种,它在用户与菜单、快捷键、控件交互时产生,传递控制ID和...

    C++消息处理[参考].pdf

    `ON_UPDATE_COMMAND_UI`和`ON_UPDATE_COMMAND_UI_RANGE`宏用于处理这类消息。 总之,C++中的MFC消息处理机制是通过宏和消息映射机制来实现的,它使得开发者能够方便地处理Windows环境下的各种用户交互和系统事件,...

    MFC 消息类型(详解)

    - `ON_COMMAND_EX(ID, pfn)`:用于处理多个对象共享同一命令ID的情况,返回值改为`BOOL`,以决定是否继续处理。 - `ON_COMMAND_RANGE(nID, nLastID, pfn)`:处理连续ID范围内的命令,通过函数参数确定具体被点击的...

    VB写的摄像头家庭监

    Case msghinstance.WM_KEYDOWN, msghinstance.WM_KEYUP, msghinstance.WM_SYSCOMMAND, msghinstance.WM_COMMAND, _ msghinstance.WM_ACTIVATEAPP, msghinstance.WM_NCACTIVATE, msghinstance.WM_QUERYOPEN msgproc =...

    Hook程序-无焦点的CommandButton控件.zip_COMMAND_hook

    在这个名为"Hook程序-无焦点的CommandButton控件.zip_COMMAND_hook"的压缩包中,我们可以推测它包含了一个示例,展示了如何在没有焦点的情况下处理CommandButton控件的点击事件。这种技术通常在开发用户界面时很有用...

    Visual C 教学课件:第7章 文档视图结构.ppt

    同时,ON_UPDATE_COMMAND_UI宏则用于更新界面状态,确保菜单项的可用性与当前程序状态一致。 在消息映射过程中,ON_COMMAND宏定义了一个处理WM_COMMAND消息的函数,例如: ```cpp ON_COMMAND(IDC_OPEN_FILE, ...

    wParam和lParam消息

    菜单消息:WM_INITMENU、WM_MENUSELECT、WM_INITMENUPOPUP、WM_COMMAND - `WM_INITMENU`:初始化菜单消息,`wParam`指向菜单句柄,`lParam`通常为0。 - `WM_MENUSELECT`:选择菜单项消息,`wParam`包含了所选菜单...

    Windows程序设计参数wParam和lParam消息的含义

    按钮子窗口的WM_COMMAND消息 当按钮被点击时触发此消息。 - `wParam`:低位是子窗口ID,高位是通知码。 - `lParam`:子窗口句柄。 #### 10. 焦点消息 (WM_KILLFOCUS 和 WM_SETFOCUS) 这些消息处理焦点的变化。 -...

    win32环境下的按钮重绘

    6. **WM_COMMAND消息**:当用户与按钮交互时发送,例如点击按钮。通过处理这个消息,我们可以响应用户的操作。 7. **DrawState函数**:用于在窗口上绘制状态化的图标或文本,例如,根据按钮的状态(如按下、悬浮等...

Global site tag (gtag.js) - Google Analytics