WM_COMMAND

news/2024/11/9 14:18:32

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  

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

 

 

CString与LPCWSTR的转化
问题起因: 
   
      
   
     //  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)

     所有的宏如下表所示: 

A2BSTROLE2AT2AW2A
A2COLEOLE2BSTRT2BSTRW2BSTR
A2CTOLE2CAT2CAW2CA
A2CWOLE2CTT2COLEW2COLE
A2OLEOLE2CWT2CWW2CT
A2TOLE2TT2OLEW2OLE
A2WOLE2WT2WW2T

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

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

    利用这些宏,可以快速的进行各种字符间的转换。使用前必须包含头文件,并且申明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());


http://www.niftyadmin.cn/n/3711232.html

相关文章

apache2.2.6配置PHP5.2.4解说[转]

忙乎了一个通宵,没搞定Apache 2.2.6配置PHP 5.24的环境,到处gg来的信息,也都是空谈,毫无见效.发现Apache新版把一些配置分开了,分别由几个conf文件分担,各司其职,并且加强了proxy的性能.现在就讲讲在Apache2.2.6中配置php5.24的环境吧.首先假设php5的文件是C:\PHP中httpd.conf中…

如何充分利用C#匿名方法的平台优势

C# 1.1里&#xff0c;声明和使用委托要求你有委托和一个在委托被触发时具有匹配签名的能够执行的方法&#xff0c;以及一个将命名方法与委托关联的分配语句。作为C# 2.0的新特性&#xff0c;匿名方法基本上能够提供与先前命名方法相同的功能&#xff0c;但是它已经不再需要一个…

【转】论函数调用约定

假设我们有这样的一个函数&#xff1a; int function(int a,int b) 调用时只要用result function(1,2)这样的方式就可以使用这个函数。但是&#xff0c;当高级语言被编译成计算机可以识别的机器码时&#xff0c;有一个问题就凸现出来&#xff1a;在CPU中&#xff0c;计算 机…

Microsoft C 和 C++ 编译器与链接器

CL.exe 是控制 Microsoft C 和 C 编译器与链接器的 32 位工具。编译器产生通用对象文件格式 (COFF) 对象 (.obj) 文件。链接器产生可执行文件 (.exe) 或动态链接库文件 (DLL)。 注意&#xff0c;所有编译器选项都区分大小写。 若要编译但不链…

Open CV系列学习笔记(六)模糊操作 2021-01-31

Open CV系列学习笔记&#xff08;六&#xff09;模糊操作 什么是模糊操作&#xff1f; 模糊操作的作用是在图片时减低噪声。 模糊操作有均值模糊&#xff0c;中值模糊&#xff0c;高斯模糊和自定义模糊 模糊操作的基本原理&#xff1a; 1、基于离散卷积 2、定义好每一个卷积核…

转贴C/C++用移位实现乘除法运算,提高运行效率

用移位实现乘除法运算 aa*4; bb/4; 可以改为&#xff1a; aa<<2; bb>>2; 说明&#xff1a; 除2 右移1位 乘2 左移1位 除4 右移2位 乘4 左移2位 除8 右移3位 乘8 左移3位 ... ... 通常如果需要乘以或除以2的n次方&#xff0c;都可以用移位的方法代替。 大部分…

Open CV系列学习笔记(七)边缘保留滤波(EPF) 2021-02-01

Open CV系列学习笔记&#xff08;七&#xff09;边缘保留滤波(EPF) 高斯双边 双边滤波&#xff08;Bilateral filter&#xff09;是一种非线性的滤波方法&#xff0c;是结合图像的空间邻近度和像素值相似度的一种折中处理&#xff0c;同时考虑空域信息和灰度相似性&#xff0c…

c++位运算,|,~,^,,

关键字&#xff1a;c位运算 什么是位(bit)&#xff1f; 很简单&#xff0c;位(bit)就是单个的0或1&#xff0c;位是我们在计算机上所作一切的基础。计算机上的所有数据都是用位来存储的。一个字节(BYTE)由八个位组成&#xff0c;一个字(WORD)是二个字节或十六位&#xff0c;一…