什么是LPCTSTR?


37

什么是LPCTSTRLPCTSTR-like(例如HDC)及其代表什么?



3
这就是为什么我们只喜欢Microsoft。
zxcdw

2
那些“类型”总是表现出惊喜,例如,当您这样做LPCSTR p, q;并且想要拥有时const char *p, *q;。您可以拒绝使用它们吗?
ott--

9
可恶的。
Thomas Eding

2
32位应用程序的64位移植需要此类术语的知识
过度交换

Answers:


76

在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

29
每次看到该类型名称,我都会感到畏缩。只是让我感到不舒服。(+1 BTW)
Donal Fellows 2013年

2
那我什么时候应该使用这种指针呢?
Florian Margaine 2013年

@FlorianMargaine当API告诉您。只需使用“适当的”类型在那之前
詹姆斯

1
请注意,这里有很多注意事项。wchar_t是16位类型,但可用于存储ucs2和utf-16编码的unicode字符。utf-16可以使用多个wchar_t对单个字母进行编码,而ucs2仅支持unicode字符集的子集。您需要调用哪些API函数还取决于所使用的编码。
萧伯纳

2
最糟糕的是DWORD,它曾经是32位的双字,但如今是32位的半字:-)
gnasher729

6

无需使用任何与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上运行项目,就没有关系。


0

这些类型记录在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;

0

我知道这个问题是在很久以前问过的,我并不想直接回答确切的原始问题,但是由于这个特殊的问/答评级很高,因此我想在这里为以后的读者添加一些内容。这必须与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函数来分解它:首先是函数的参数HINSTANCEPSTR

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;
  • ......等等,例如HBRUSHHCURSORHBITMAPHDCHDESK,等。

这些都是typedefs正在使用一个声明typedef这是一个HANDLEHANDLE本身被声明为typedef来自PVOID这也是typedef一个void pointer


所以说到LPCTSTR我们可以在相同的文档中找到它:

它定义为LPCWSTRif UNICODE定义,否则为LPCSTRelse。

#ifdef UNICODE
  typedef LPCWSTR LPCSTR;
#else
  typedef LPCSTR LPCTSTR;
#endif

因此,希望这将对如何理解typedefs尤其是Windows数据类型的用法提供指导,尤其是在Windows数据类型Win32 API


HANDLE如果您激活STRICT宏,则许多句柄类型的类型比仅仅是别名的类型更强。我认为这是新项目中的默认设置。
塞巴斯蒂安·雷德尔

@SebastianRedl可能是;但是我并不想深入探讨API和语言强类型方面的严格性。通过使用typedef可以更全面地了解Win32 API及其数据类型...
Francis Cugler
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.