web-dev-qa-db-fra.com

Qu'est-ce que LPCTSTR?

à quoi ressemblent LPCTSTR et LPCTSTR (par exemple HDC) et ce que cela signifie?

38
user61273

Citant Brian Kramer sur les forums MSDN

LPCTSTR = [~ # ~] l [~ # ~] ‌ong [~ # ~ ] p [~ # ~] ‌pointeur vers un [~ # ~] c [~ # ~] ‌onst [~ # ~] t [~ # ~] ‌CHAR [~ # ~] str [~ # ~] ‌ing (Ne vous inquiétez pas, un long pointeur est identique à un pointeur. Il y avait deux versions de pointeurs sous des fenêtres 16 bits.)

Voici le tableau:

  • LPSTR = char*
  • LPCSTR = const char*
  • LPWSTR = wchar_t*
  • LPCWSTR = const wchar_t*
  • LPTSTR = char* or wchar_t* cela dépend de _UNICODE
  • LPCTSTR = const char* or const wchar_t* cela dépend de _UNICODE
78
fellahst

Il n'est pas nécessaire d'utiliser les types relatifs à TCHAR.

Ces types, tous les types de structure qui les utilisent et toutes les fonctions associées sont mappés au moment de la compilation sur une version ANSI ou UNICODE (en fonction de la configuration de votre projet). Les versions ANSI ont généralement un A ajouté à la fin du nom, et les versions Unicode ajoutent un W. Vous pouvez les utiliser explicitement si vous préférez. MSDN le notera si nécessaire, par exemple, il répertorie une fonction MessageBoxIndirectA et MessageBoxIndirectW ici: http://msdn.Microsoft.com/en-us/library/windows/desktop/ms645511 (v = vs.85) .aspx

À moins que vous ne cibliez Windows 9x, qui manquait d'implémentations de nombreuses fonctions Unicode, il n'est pas nécessaire d'utiliser les versions ANSI. Si vous ciblez Windows 9x, vous pouvez utiliser TCHAR pour créer un binaire ansi et unicode à partir de la même base de code, tant que votre code ne fait aucune hypothèse quant à savoir si TCHAR est un char ou un wchar.

Si vous ne vous souciez pas de Windows 9x, je vous recommande de configurer votre projet comme unicode et de traiter TCHAR comme identique à WCHAR. Vous pouvez utiliser explicitement les fonctions et types W si vous préférez, mais tant que vous ne prévoyez pas d'exécuter votre projet sur Windows 9x, cela n'a pas vraiment d'importance.

6
Vincent Povirk

Ces types sont documentés à Windows Data Types sur MSDN:

LPCTSTR

Un LPCWSTR si UNICODE est défini, un LPCSTR sinon. Pour plus d'informations, consultez Types de données Windows pour les chaînes.

Ce type est déclaré dans WinNT.h comme suit:

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

LPCWSTR

Pointeur vers une chaîne constante terminée par un caractère nul de caractères Unicode 16 bits. Pour plus d'informations, voir Jeux de caractères utilisés par les polices.

Ce type est déclaré dans WinNT.h comme suit:

typedef CONST WCHAR *LPCWSTR;

HDC

Un handle vers un contexte de périphérique (DC).

Ce type est déclaré dans WinDef.h comme suit:

typedef HANDLE HDC;
1
CodesInChaos

Je sais que cette question a été posée il y a un certain temps et je n'essaie pas de répondre directement à la question d'origine exacte, mais comme ce Q/A particulier a une note décente, je voudrais ajouter un peu ici pour les futurs lecteurs. Cela concerne plus spécifiquement le Win32APItypedefs et comment les comprendre.

Si quelqu'un a déjà fait de la programmation Windows à l'époque des machines 32 bits de Windows 95 à Windows 7-8, il comprend et sait que le Win32API est chargé avec typedefs et qu'une majorité de leurs fonctions et structures qui doivent être remplies et utilisées en dépendent fortement.


Voici un programme de base pour Windows à titre de démonstration.

#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;
}

C'est à peine assez de code pour rendre une application Windows. C'est la configuration la plus basique pour initialiser les propriétés minimales nues pour rendre une fenêtre de base et comme vous pouvez le voir, elle est déjà chargée avec typedefs à partir de Win32api.


Décomposons-le en regardant les fonctions WinMain et InitWindowsApp: La première chose est les paramètres des fonctions HINSTANCE et PSTR:

WinMain accepte un seul objet HINSTANCE tandis que InitWindowsApp accepte deux objets HINSTANCE un objet PSTR ou une autre chaîne typedef et un int.

J'utiliserai ici la fonction InitWindowsApp car elle donnera une description de l'objet dans les deux fonctions.

Le premier HINSTANCE est défini comme un [~ # ~] h [~ # ~] andle à un [~ # ~] instance [~ # ~] et c'est celle qui est la plus utilisée pour l'application. Le second est un autre HANDLE vers une instance précédente [~ # ~] [~ # ~] qui est rarement utilisée. Il a été conservé à des fins héritées afin de ne pas avoir à modifier la signature de fonction WinMain() qui casserait de nombreuses applications déjà existantes dans le processus. Le troisième paramètre est un [~ # ~] p [~ # ~] ointer vers un [~ # ~ ] str [~ # ~] ing.

Nous devons donc nous demander ce qu'est un HANDLE? Si nous regardons dans les documents Win32API trouvés ici: Windows Data Types nous pouvons facilement le rechercher et voir qu'il est défini comme:

Une poignée à un objet. Ce type est déclaré dans WinNT.h comme suit:

typedef PVOID HANDLE; 

Nous avons maintenant un autre typedef. Qu'est-ce qu'un PVOID? Eh bien, cela devrait être évident, mais regardons cela dans le même tableau ...

Un pointeur vers n'importe quel type. Ceci est déclaré dans WinNT.h

typedef void *PVOID;

Un HANDLE est utilisé pour déclarer de nombreux objets dans les éléments Win32API tels que:

  • HKEY - Un handle vers une clé de registre. Déclaré dans WinDef.h
    • typdef HANDLE HKEY;
  • HKL - Un handle vers un identificateur de paramètres régionaux. Déclaré dans WinDef.h
    • typdef HANDLE HKL;
  • HMENU - Un handle vers un menu. Déclaré dans WinDef.h
    • typdef HANDLE HMENU;
  • HPEN - Une poignée pour un stylo. Déclaré dans WinDef.h
    • typedef HANDLE HPEN;
  • HWND - Un handle vers une fenêtre. Déclaré dans WinDef.h
    • typedef HANDLE HWND;
  • ... et ainsi de suite tels que HBRUSH, HCURSOR, HBITMAP, HDC, HDESK, etc.

Ce sont tous typedefs qui sont déclarés à l'aide d'un typedef qui est un HANDLE et le HANDLE lui-même est déclaré comme un typedef à partir d'un PVOID qui est aussi un typedef vers un void pointer.


Donc, quand il s'agit de LPCTSTR, nous pouvons trouver que dans les mêmes documents:

Il est défini comme un LPCWSTR si UNICODE est défini ou un LPCSTR sinon.

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

J'espère donc que cela vous aidera à comprendre comment utiliser typedefs en particulier avec les Types de données Windows que vous pouvez trouver dans le Win32API.

0
Francis Cugler