例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的低字中(LOWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。
举我们选择菜单的例子,当选择了一个菜单项的时候,Windows向菜单所属的窗口发送WM_COMMAND消息;而用户按下了一个加速键的时候,windows向TranslateAccelerate函数指定的目标窗口发送WM_COMMAND消息。一般这两者对应的窗口都是主窗口,所以在主窗口中的窗口过程中集中处理WM_COMMAND消息,而不必考虑它究竟是菜单引发的还是加速键引发的。
int WINAPI WinMain(HINSTANCE hInstance ,HINSTANCE hPrevInstance,PSTR szCmdLine ,int iCmdShow)
EnableWindow(GetDlgItem(hwnd, 1002), Edit_GetTextLength(GetDlgItem(hwnd,1001)) > 0);
fok= FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_ALLOCATE_BUFFER,NULL,dwError,systemLocale,(PTSTR)&hlocal,0,NULL);
fok = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_IGNORE_INSERTS,hDLL,dwError,systemLocale,(PTSTR)&hlocal,0,NULL);
核心编程--第二章
typedef char CHAR
typedef wchar_t WCHAR
typedef CAHR *PCHAR
typedef CHAR *PSTR
typedef CONST CHAR *PCSTR
typedf WCHAR *PWCHAR
typedf WCHAR *PWCHAR
typedef WCHAR *PWSTR
typedef CONST WCHAR *PCWSTR
#ifdef UNICODE
typedef WCHAR TCHAR ,*PTCHAR,PTSTR
typedef CONST WCHAR *PCTSTR
#define _TEXT(quote) quote
#else
typedef CHAR TCHAR ,*PTCHAR,PTSTR;
typedef CONST CHAR *PCTSTR
#define _TEXT(quote) quote
#endif
#define TEXT(quote) _TEXT(quote)
C运行库中的Unicode函数和ANSI函数
_tcslen :strlen--wcslen ---------返回字符串长度
_countof用啦计算啊一个静态分配的数组中的元素的个数
sizeof用来计算字节数
eg
#include <Windowsx.h>
#include <tchar.h>
#include <Windows.h>
#include <errno.h>
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
TCHAR szBefore[5] = {L‘B‘,L‘B‘,L‘B‘,L‘B‘,L‘\0‘};
TCHAR szBuffer[10] = {L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘\0‘};
TCHAR szAfter[5] = {L‘A‘,L‘A‘,L‘A‘,L‘A‘,L‘\0‘};
errno_t resulr = _tcscpy_s(szBuffer,_countof(szBuffer),L"0123456789");
return 0;
}
这个函数会造成溢出。下面是改进,但是还是会少一位。下面这个函数有截断作用。可以防止溢出
#include <Windowsx.h>
#include <tchar.h>
#include <Windows.h>
#include <errno.h>
#include <strsafe.h>
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
TCHAR szBefore[5] = {L‘B‘,L‘B‘,L‘B‘,L‘B‘,L‘\0‘};
TCHAR szBuffer[10] = {L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘-‘,L‘\0‘};
TCHAR szAfter[5] = {L‘A‘,L‘A‘,L‘A‘,L‘A‘,L‘\0‘};
errno_t resulr = StringCchCopy(szBuffer,_countof(szBuffer),L"0123456789");
return 0;
}
windows字符串函数:
CompareString 函数:
eg:
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <Windows.h>
#include <tchar.h>
#include <Shlwapi.h>
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
TCHAR val[] = L"xiaopao";
TCHAR val2[] = L"xiao";
LCID hcid ;
hcid = GetThreadLocale();
int k ;
k = CompareString(hcid,NORM_IGNORECASE,val,_tcslen(val),val2,_tcslen(val2));
if (k == 0 )
{
MessageBox(NULL,L"函数调用失败",L"Compare",MB_OK);
}
if (k == 1)
{
MessageBox(NULL,L"string1 < string2",L"Compare",MB_OK);
}
if(k == 2)
{
MessageBox(NULL,L"string1 = string2",L"Compare",MB_OK);
}
if ( k == 3 )
MessageBox(NULL,L"string1 >string2",L"Compare",MB_OK);
return 0;
}
---------------------------------------------------------------------------------------------------------------------
科普:
为什么要用UNICODE
1:UNICODE有利于应用程序的本地化
2:使用Unicode,只需发布一个二进制(.exe或DLL)文件,就可以支持所有语言
3:Unicode提升了应用程序的效率,因为代码执行速度更快,占用内存更少。Windows内部的一切工作都是使用Unicode字符和Unicode字符串,所以,假如我们坚持传入ANSI字符或字符串,Windows就会被迫分配内存,并将ANSI字符或字符串转换为等价的Unicode
4:使用Unicode,应用程序可以轻松调用所有尚未被弃用的Windows函数,因为一些windows函数提供的版本只能处理unicode字符和字符串
5:应用程序很容易与COM集成
6:应用程序很容易与.NET Framework集成
7:能保证应用程序的代码能够轻松操作我们自己的资源。
推荐的字符和字符串处理方式:
1:开始将文本字符串想象为字符的数组,而不是char或字节的数组
2:用通用数据类型(TCAHR/PTSTR)来表示文本字符和字符串
3:用明确的数据类型(如BYTE/PBYTE)来表示字节 字节、字节指针和数据缓冲区
4:用TEXT或_T宏来表示字面量字符和字符串,但为了保持一致性和更好的可读性,避免两者的混用
5:执行全局替换(PTSTR替换PSTR)
6:避免使用printf系列函数 应使用MultiByteToWideChar和WideCharToMultiByte
7:_countof()-->sizeof() malloc(nCharacters*sizeof(TCHAR)) ----->malloc(nCharacters)
8:UNICODE与_UNICODE符号要么不定义,要么同时定义
字符串处理函数应该遵循的基本准则:
1:始终使用安全的字符串处理函数,eg后缀为_s的函数,或者是前缀为StringCch的函数
2:不要使用不安全的C运行库字符串处理函数,一般情况下,如果一个缓冲区处理函数的参数中不包括目标缓冲区的长度,那么我们就应该避免使用这样的函数,同时还应避免自己实现这样的函数
3:利用/GS和/RTCs编译器标志来自动检测缓冲区溢出
4:不要用Kernel32方法进行字符串处理
5:字符串比较CompareString CompareStringOrdinal
多字节字符转换为宽字节字符
函数:
int MultiByteToWideChar(
UINT CodePage, //CP_ACP代码页就实现了ANSI与Unicode之间的转换CP_UTF8代码页就实现了UTF-8与Unicode之间的转换
DWORD dwFlags, //一般为0
LPCSTR lpMultiByteStr, //指定要传的字符串
int cchMultiByte, //字符串长度,-1时自己计算长度
LPWSTR lpWideCharStr, //目的字符串
int cchWideChar //目的字符串长度
);
eg:
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <tchar.h>
#include <Shlwapi.h>
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
char val[]="xiaopao";
int k ;
wchar_t * val2 ;
k = MultiByteToWideChar(CP_ACP,0,val,-1,NULL,0); //分配一块足以容纳转换后的Unicode字符串的内存
val2 = new wchar_t[k*sizeof(wchar_t)+1];
MultiByteToWideChar(CP_ACP,0,val,-1,val2,k);
MessageBox(NULL,val2,L"Hello",MB_OK);
return 0;
}
---------------------------------------------------------------------------------------------------------------------
宽字节字符转换为多字节字符
int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPWSTR lpWideCharStr,
int cchWideChar,
LPCSTR lpMultiByteStr,
int cchMultiByte,
LPCSTR lpDefaultChar,
PBOOL pfUsedDefaultChar
);
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <tchar.h>
#include <Shlwapi.h>
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
TCHAR val[]=L"xiaopao";
int k ;
char * val2 ;
TCHAR val3[20];
k = WideCharToMultiByte(CP_ACP,0,val,-1,NULL,0,NULL,NULL); //分配一块足以容纳转换后的Unicode字符串的内存
val2 = new char[k+1];
memset((void*)val2,0,sizeof(char)*(k+1));
WideCharToMultiByte(CP_ACP,0,val,-1,val2,k,NULL,NULL);
return 0;
}
---------------------------------------------------------------------------------------------------------------------
字符串的逆转---有中变量
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <tchar.h>
#include <Shlwapi.h>
PWSTR StringReverseW(PWSTR pWideCharStr ,DWORD cchLength );
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
PWSTR val = L"xiaopao";
int k = 0 ;
k =wcslen(val);
StringReverseW(val,k);
return 0;
}
PWSTR StringReverseW(PWSTR pWideCharStr, DWORD cchLength)
{
PWSTR pEndOfStr = pWideCharStr + wcsnlen_s(pWideCharStr, cchLength) - 1;
PWSTR pResult = (WCHAR*)malloc(sizeof(WCHAR));
WCHAR * p=pResult;
wchar_t cCharT;
int i = 0;
int k = wcslen(pResult);
while (cchLength)
{
pEndOfStr--;
cchLength--;
cCharT = *pEndOfStr;
*p = cCharT;
p++;
}
MessageBox(NULL, pResult, L"Hello", MB_OK);
return pResult;
}
---------------------------------------------------------------------------------------------------------------------
字符串逆转--无中间变量
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <tchar.h>
#include <Shlwapi.h>
PWSTR StringReverseW(PWSTR pWideCharStr ,DWORD cchLength );
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
PWSTR val = L"xiaopao";
int k = 0 ;
k =wcslen(val);
StringReverseW(val,k);
return 0;
}
PWSTR StringReverseW(PWSTR pWideCharStr, DWORD cchLength)
{
PWSTR pEndOfStr = pWideCharStr + wcsnlen_s(pWideCharStr, cchLength) - 1;
PWSTR pResult = (TCHAR*)malloc(cchLength*sizeof(TCHAR));
wchar_t cCharT;
int i = 0;
int k = wcslen(pResult);
while (cchLength)
{
pEndOfStr--;
cchLength--;
cCharT = *pEndOfStr;
*pResult = cCharT;
pResult++;
}
pResult--;
pResult--;
pResult--;
pResult--;
pResult--;
pResult--;
MessageBox(NULL, pResult, L"Hello", MB_OK);
return pResult;
}
---------------------------------------------------------------------------------------------------------------------
多字节字符串的逆转
---------------------------------------------------------------------------------------------------------------------
//引入库文件
#include <Windowsx.h>
#include <tchar.h>
#include <Shlwapi.h>
//声明方法
BOOL StringReverseW(PWSTR pWideCharStr ,DWORD cchLength );
BOOL StringReverseA(PSTR pMultiByteStr, DWORD cchLength);
//调用
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
PSTR val = "xiaopao";
int k = 0 ;
k =strlen(val);
StringReverseA(val,k);
return 0;
}
//实现
BOOL StringReverseW(PWSTR pWideCharStr, DWORD cchLength)
{
PWSTR pEndOfStr = pWideCharStr + wcsnlen_s(pWideCharStr, cchLength) - 1;
PWSTR pResult = (WCHAR*)malloc(sizeof(WCHAR));
WCHAR * p=pResult;
wchar_t cCharT;
int i = 0;
int k = wcslen(pResult);
while (cchLength)
{
pEndOfStr--;
cchLength--;
cCharT = *pEndOfStr;
*p = cCharT;
p++;
}
return TRUE;
}
BOOL StringReverseA(PSTR pMultiByteStr, DWORD cchLength)
{
PWSTR pWideCharStr ;
int nLenOfWideCharStr ;
BOOL fOk = FALSE;
nLenOfWideCharStr =MultiByteToWideChar (CP_ACP,0,pMultiByteStr,cchLength,NULL,0);
pWideCharStr = (PWSTR)HeapAlloc(GetProcessHeap(),0,nLenOfWideCharStr*sizeof(wchar_t));
if (pWideCharStr == NULL)
return NULL;
MultiByteToWideChar (CP_ACP,0,pMultiByteStr,cchLength,pWideCharStr,nLenOfWideCharStr);
fOk = StringReverseW(pWideCharStr,cchLength);
if (fOk)
{
WideCharToMultiByte(CP_ACP,0,pWideCharStr,cchLength,pMultiByteStr,(int)strlen(pMultiByteStr),NULL,NULL);
}
HeapFree(GetProcessHeap(),0,pWideCharStr);
return TRUE;
}
---------------------------------------------------------------------------------------------------------------------
注:HeapAlloc它用来在指定的堆上分配内存,并且分配后的内存不可移动
LPVOID HeapAlloc(
HANDLE hHeap,
DWORD dwFlags,
SIZE_T dwBytes,
);
hHeap
要分配堆的句柄,可以通过HeapCreate()函数或GetProcessHeap()函数获得。
dwFlags
堆分配时的可选参数,其值可以为以下的一种或多种:
值
|
意义
|
HEAP_GENERATE_EXCEPTIONS
|
如果分配错误将会抛出异常,而不是返回NULL。异常值可能是STATUS_NO_MEMORY, 表示获得的内存容量不足,或是STATUS_ACCESS_VIOLATION,表示存取不合法。
|
HEAP_NO_SERIALIZE
|
不使用连续存取。
|
HEAP_ZERO_MEMORY
|
将分配的内存全部清零。
|
dwBytes
要分配堆的字节数。