什么是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*
取决于_UNICODE
LPCTSTR
=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
。
让我们通过查看WinMain
and InitWindowsApp
函数来分解它:首先是函数的参数HINSTANCE
和PSTR
:
WinMain
接受一个HINSTANCE
对象,而InitWindowsApp
接受两个HINSTANCE
对象,一个PSTR对象或其他typedef
字符串和一个整数。
我将在InitWindowsApp
这里使用该函数,因为它将在两个函数中都提供对象的描述。
第一HINSTANCE
被定义为ħ andle到INSTANCE并且这是最常用的应用程序的一个。第二个是HANDLE
Previous 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
我们可以在相同的文档中找到它:
它定义为
LPCWSTR
ifUNICODE
定义,否则为LPCSTR
else。
#ifdef UNICODE
typedef LPCWSTR LPCSTR;
#else
typedef LPCSTR LPCTSTR;
#endif
因此,希望这将对如何理解typedefs
尤其是Windows数据类型的用法提供指导,尤其是在Windows数据类型中Win32
API
。
HANDLE
如果您激活STRICT
宏,则许多句柄类型的类型比仅仅是别名的类型更强。我认为这是新项目中的默认设置。