什么是LPCTSTR和LPCTSTR-like(例如HDC)及其代表什么?
LPCSTR p, q;并且想要拥有时const char *p, *q;。您可以拒绝使用它们吗?
什么是LPCTSTR和LPCTSTR-like(例如HDC)及其代表什么?
LPCSTR p, q;并且想要拥有时const char *p, *q;。您可以拒绝使用它们吗?
Answers:
在MSDN论坛上引用Brian Kramer
LPCTSTR= 大号翁P ointer到ç onst Ť CHAR STR荷兰国际集团(不用担心,长指针相同的指针。有指针的两种口味下16位的窗口。)这是桌子:
LPSTR=char*LPCSTR=const char*LPWSTR=wchar_t*LPCWSTR=const wchar_t*LPTSTR=char* or wchar_t*取决于_UNICODELPCTSTR=const char* or const wchar_t*取决于_UNICODE
无需使用任何与TCHAR相关的类型。
这些类型,使用它们的所有结构类型以及所有相关功能在编译时都映射到ANSI或UNICODE版本(基于项目的配置)。ANSI版本通常在名称末尾附加A,而unicode版本则附加W。如果愿意,可以显式使用它们。MSDN将在必要时对此进行说明,例如,它在此处列出了MessageBoxIndirectA和MessageBoxIndirectW函数:http : //msdn.microsoft.com/zh-cn/library/windows/desktop/ms645511( v=vs.85) .aspx
除非您的目标是缺少许多Unicode功能实现的Windows 9x,否则就无需使用ANSI版本。如果您的目标是Windows 9x,则可以使用TCHAR从相同的代码库构建ansi和unicode二进制文件,只要您的代码不假定TCHAR是char还是wchar。
如果您不关心Windows 9x,建议您将项目配置为unicode,并将TCHAR视为与WCHAR相同。如果愿意,可以显式使用W函数和类型,但是只要您不打算在Windows 9x上运行项目,就没有关系。
这些类型记录在MSDN 上的Windows数据类型中:
LPCTSTR一个
LPCWSTR如果UNICODE被定义,一个LPCSTR否则。有关更多信息,请参见Windows字符串数据类型。在WinNT.h中声明此类型,如下所示:
#ifdef UNICODE typedef LPCWSTR LPCTSTR; #else typedef LPCSTR LPCTSTR; #endif
LPCWSTR指向以16位Unicode字符为常数的,以空字符终止的常量的指针。有关更多信息,请参见字体使用的字符集。
在WinNT.h中声明此类型,如下所示:
typedef CONST WCHAR *LPCWSTR;
HDC设备上下文(DC)的句柄。
在WinDef.h中声明此类型,如下所示:
typedef HANDLE HDC;
我知道这个问题是在很久以前问过的,我并不想直接回答确切的原始问题,但是由于这个特殊的问/答评级很高,因此我想在这里为以后的读者添加一些内容。这必须与Win32 API typedefs以及如何理解它们有关。
如果有人曾经在从Windows 95到Windows 7-8的32位计算机时代执行过任何Windows编程,他们就会了解并知道该工具Win32 API已加载,typedefs并且它们的大部分功能和结构都将被填充和使用过依赖于他们。
这是一个基本的Windows程序作为演示。
#include <Windows.h>
HWND ghMainWnd = 0;
bool InitWindowsApp( HINSTANCE, int show );
LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
int run();
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int show ) {
if ( !InitWindowsApp( hInstance, showCmd ) ) {
return 0;
}
return run();
}
LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {
switch( msg ) {
case WM_KEYDOWN: {
if ( wParam == VK_ESCAPE ) {
DestroyWindow( ghMainWnd );
}
return 0;
}
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
default: {
return DefWindowProc( hWnd, msg, wParam, lParam );
}
}
}
bool InitWindowsApp( HINSTANCE hInstance, int nCmdShow ) {
WNDCLASSEX wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.lpszMenuName = NULL;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszClassName = L"Basic Window";
wc.cbSize = sizeof( WNDCLASSEX);
if ( !RegisterClassEx( &wc ) ) {
MessageBox( NULL, L"Register Class FAILED", NULL, NULL );
return false;
}
ghMainWnd = CreateWindow(
L"Basic Window",
L"Win32Basic",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, NULL,
hInstance,
NULL );
if ( ghMainWnd == 0 ) {
MessageBox( NULL, L"Window failed to create", L"Error", MB_OK );
return false;
}
ShowWindow( ghMainWnd, nCmdShow );
UpdateWindow( ghMainWnd );
return true;
}
int run() {
MSG msg = {0};
BOOL bReturn = 1;
while( (bReturn = GetMessage( &msg, NULL, NULL, NULL)) != 0 ) {
if ( bReturn == -1 ) {
MessageBox( NULL, L"GetMessage FAILED", L"Error", MB_OK );
break;
} else {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
return (int)msg.wParam;
}
这仅够渲染Windows应用程序的代码。这是最基本的设置,用于初始化裸露的最小属性以呈现基本窗口,并且您可以看到它已经typedefs从中加载Win32 api。
让我们通过查看WinMainand InitWindowsApp函数来分解它:首先是函数的参数HINSTANCE和PSTR:
WinMain接受一个HINSTANCE对象,而InitWindowsApp接受两个HINSTANCE对象,一个PSTR对象或其他typedef字符串和一个整数。
我将在InitWindowsApp这里使用该函数,因为它将在两个函数中都提供对象的描述。
第一HINSTANCE被定义为ħ andle到INSTANCE并且这是最常用的应用程序的一个。第二个是HANDLEPrevious INSTANCE的另一个,现在已经很少使用了。它被保留用于传统目的,以便不必更改WinMain()会破坏该过程中许多现有应用程序的功能签名。第三个参数是一个P ointer到STR ING。
因此,我们必须问自己是什么HANDLE?如果我们查看在以下Win32 API文档中找到的内容:Windows数据类型,我们可以轻松地查找它,并将其定义为:
对象的句柄。在WinNT.h中声明此类型,如下所示:
typedef PVOID HANDLE;
现在我们有了另一个typedef。什么是PVOID?好吧,这应该很明显,但是让我们在同一张表中查找...
指向任何类型的指针。这在WinNT.h中声明
typedef void *PVOID;
A HANDLE用于在Win32 API事物中声明许多对象,例如:
HKEY -注册表项的句柄。在WinDef.h中声明
typdef HANDLE HKEY;HKL -语言环境标识符的句柄。在WinDef.h中声明
typdef HANDLE HKL;HMENU -菜单的句柄。在WinDef.h中声明
typdef HANDLE HMENU;HPEN -笔的手柄。在WinDef.h中声明
typedef HANDLE HPEN;HWND -窗户的把手。在WinDef.h中声明
typedef HANDLE HWND;HBRUSH,HCURSOR,HBITMAP,HDC,HDESK,等。这些都是typedefs正在使用一个声明typedef这是一个HANDLE和HANDLE本身被声明为typedef来自PVOID这也是typedef一个void pointer。
所以说到LPCTSTR我们可以在相同的文档中找到它:
它定义为
LPCWSTRifUNICODE定义,否则为LPCSTRelse。
#ifdef UNICODE
typedef LPCWSTR LPCSTR;
#else
typedef LPCSTR LPCTSTR;
#endif
因此,希望这将对如何理解typedefs尤其是Windows数据类型的用法提供指导,尤其是在Windows数据类型中Win32 API。
HANDLE如果您激活STRICT宏,则许多句柄类型的类型比仅仅是别名的类型更强。我认为这是新项目中的默认设置。