`
hcmfys
  • 浏览: 347638 次
  • 性别: 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 user message macroWM_COMMAND用户消息宏(5KB)

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

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

    Window 消息大全

    WM_COMMAND= $0111 //当用户选择一条菜单命令项或当某个控件发送一条消息给它的父窗口,一个快捷键被翻译 WM_SYSCOMMAND = $0112 //当用户选择窗口菜单的一条命令或当用户选择最大化或最小化时那个窗口会收到此消息...

    Visual Studio 2008写的SDK对话框程序

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

    VB写的摄像头家庭监

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

    MFC中自定义消息处理

    如果用户自定义的类要求响应普通的Windows消息(也就是以WM_开头,除了WM_COMMAND以外的消息,这类消息在WM_USER以下的是系统消息,WM_USER以上的可以由用户自己定义),那就要求自定义的类必须从CWnd中派生。...

    Windows程序设计笔记

    5、掌握WM_CREATE、WM_COMMAND、鼠标消息的处理方法 6、掌握菜单的使用(菜单消息处理) 7、掌握文件存储(设计存储结构、文件的保存与打开) 8、掌握对话框的使用和参数传递 9、掌握全局变量、外部静态变量、局部...

    Windows消息对应值

    WM_MENUCOMMAND = 0x0126, WM_CTLCOLORMSGBOX = 0x0132, WM_CTLCOLOREDIT = 0x0133, WM_CTLCOLORLISTBOX = 0x0134, WM_CTLCOLORBTN = 0x0135, WM_CTLCOLORDLG = 0x0136, WM_CTLCOLORSCROLLBAR = 0x...

    WTL消息处理

    以WM_NOTIFY和WM_COMMAND消息形式发送的通知消息包含各种信息。WM_COMMAND消息的参数包含发送通知消息的控件ID,控件的窗口句柄和通知代码,WM_NOTIFY消息的参数还包含一个NMHDR数据结构的指针。

    易语言打开文件夹视图源码

    实现方式:SendMessage (hWnd, #WM_COMMAND....)。此源码谈不上技术含量,关键是那几个视图方式的常量。查找窗口句柄的方式有很多,本论坛也有很多相关源码了,如果查找句柄失败请自己修改一下吧。@易语言入门教程。

    SystemPanel

    m_niconData.uCallbackMessage=WM_COMMAND; CString strTitle=_T("系统托盘程序测试"); _tcscpy_s(this-&gt;m_niconData.szTip,sizeof(this-&gt;m_niconData.szTip)-1,strTitle); //设置提示文本 Shell_NotifyIcon...

    twainhelper

    一个静态 TWAIN 助手类 CTwainHelper。...如果图像已准备好 (如用户确定扫描图像),窗口会收到 WM_COMMAND 消息,wParam 为 IDC_TwainHelper。此时应用程序可以调用 CTwainHelper::TransferImage() 获取图像到文件中。

    邮件 发送器 汇编代码 asm

    .elseif eax == WM_COMMAND mov eax,wParam push hWnd pop hWinMain .if ax == IDOK invoke RtlZeroMemory,addr szServer,sizeof szServer invoke RtlZeroMemory,addr szUser,sizeof szUser ...

    Visual C++中MFC消息的分类

    除WM_COMMAND之外,所有的以WM_开头的消息。从CWnd派生的类,都可以接受到这类消息。注意:标准消息并不需要我们指定处理函数名称,是默认的对应关系。 宏名称 对应消息 消息处理函数 ON_WM_CHAR WM_CHAR OnChar ON_...

    C++MFC教程

    例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。 3、未处理的消息到那里去了:M$为窗口编写了默认的窗口过程,这个窗口过程将...

    定时关机程序

    HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand); HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose); } return FALSE; } void CALLBACK Time(HWND hwnd,UINT message,UINT iTimerID,DWORD dwTime) { SYSTEMTIME i...

    Delphi Pascal API创建窗体

    WM_COMMAND: begin if (HIWORD(wParam) = BN_CLICKED) then // 单击按钮 begin case LOWORD(wParam) of // 控件ID ControlID1: begin end; ControlID2: SendMessage(hForm, WM_CLOSE, 0, 0); end; end...

    关于图形学的边缘扫描算法

    ON_WM_LBUTTONDBLCLK() ON_WM_LBUTTONDOWN() ON_WM_MOUSEMOVE() ON_WM_LBUTTONUP() //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_...

    RINGSDK包含界面库和图象库。

    注:REGCMD和REGMSG其实有一个冲突的地方,就是WM_COMMAND,这个要看WM_COMMAND放置的次序,REGMSG(WM_COMMAND)之前的 REGCMD的函数会执行,之后的REGCMD的函数则会被屏蔽,不会执行到,不管WM_COMMAND消息里是否...

Global site tag (gtag.js) - Google Analytics