LPCTSTR nedir?


37

nedir LPCTSTRve LPCTSTR(örneğin benzeri HDC) ve ne anlama geliyor?



3
Bu yüzden Microsoft'u çok seviyoruz.
zxcdw

2
Bu "türler" her zaman sürprizler sergiler, örneğin yapmak LPCSTR p, q;istediğinizde ve istediğinizde const char *p, *q;. Onları kullanmayı reddedebilir misin?
ott

9
Bir kötülük.
Thomas Eding

2
32 bitlik bir uygulama taşıma 64 bit bu terminolojinin bilgi gerektirir
overexchange

Yanıtlar:


76

MSDN forumlarında Brian Kramer'den alıntı yapmak

LPCTSTR= L ‌ong P ‌ bir C ‌ gösterisini gösterme T ‌CHAR STR ‌ing (Endişelenmeyin, uzun bir işaretçi bir işaretçi ile aynıdır. 16-bit pencerelerin altında iki işaretçi vardır.)

İşte masa:

  • LPSTR = char*
  • LPCSTR = const char*
  • LPWSTR = wchar_t*
  • LPCWSTR = const wchar_t*
  • LPTSTR= char* or wchar_t*bağlı olarak_UNICODE
  • LPCTSTR= const char* or const wchar_t*bağlı olarak_UNICODE

29
Bu tip ismi her gördüğümde sarkmak gibi hissediyorum. Beni rahatsız eden bir şey var. (+1 BTW)
Donal Fellows,

2
Bu tür işaretçiyi ne zaman kullanmalıyım?
Florian Margaine

@FlorianMargaine Bir API size söylerken. Sadece o zamana kadar 'uygun' tipleri kullanın
James

1
uyarılmalıdır, burada dikkat edilmesi gereken birçok uyarı vardır. wchar_t 16 bitlik bir türdür, ancak hem ucs2 hem de utf-16 kodlu unicode karakterleri saklamak için kullanılabilir. utf-16, tek bir harfi kodlamak için birden fazla wchar_t kullanabilir, ucs2 yalnızca unicode karakter kümesinin bir alt kümesini destekler. Hangi API işlevlerini çağırmanız gerektiği, kullanılan kodlamaya da bağlıdır.
Michael Shaw,

2
En kötüsü 32 bitlik çifte kelime olan DWORD, fakat bugünlerde 32 bitlik yarım bir kelime :-)
gnasher729

6

TCHAR ile ilgili türlerden hiçbirini kullanmanıza gerek yoktur.

Bu türler, bunları kullanan tüm yapı türleri ve ilgili tüm işlevler derleme sırasında bir ANSI veya UNICODE sürümüyle eşleştirilir (projenizin yapılandırmasına bağlı olarak). ANSI sürümlerinde genellikle adın sonuna eklenmiş bir A bulunur ve unicode sürümlerinde W eklenir. İsterseniz bunları açıkça kullanabilirsiniz. MSDN gerektiğinde bunu not edecektir, örneğin burada bir MessageBoxIndirectA ve MessageBoxIndirectW işlevini listeler: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx

Birçok unicode işlevinin uygulaması olmayan Windows 9x'i hedeflemediğiniz sürece, ANSI sürümlerini kullanmanıza gerek yoktur. Windows 9x’ü hedefliyorsanız, kodunuz TCHAR’ın char veya wchar olup olmadığına dair hiçbir varsayımda bulunmadığı sürece, aynı kod tabanından bir ansi ve unicode ikili oluşturmak için TCHAR kullanabilirsiniz.

Windows 9x'i önemsemiyorsanız, projenizi unicode olarak yapılandırmanızı ve TCHAR'ı WCHAR ile aynı şekilde değerlendirmenizi öneriyorum. İsterseniz W işlevlerini ve türlerini açıkça kullanabilirsiniz, ancak projenizi Windows 9x'te çalıştırmayı planlamıyorsanız, bunun önemi yoktur.


0

Bu türler MSDN'deki Windows Veri Türlerinde belgelenmiştir :

LPCTSTR

Bir LPCWSTRif UNICODEtanımlanmış, LPCSTRbaşka türlü. Daha fazla bilgi için, bkz. Dizeler için Windows Veri Türleri.

Bu tür WinNT.h dosyasında aşağıdaki şekilde bildirilmiştir:

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

LPCWSTR

16 bitlik Unicode karakterlerden oluşan boş sonlandırılmış bir dizgeye bir işaretçi. Daha fazla bilgi için, bkz. Yazı Tipleri Tarafından Kullanılan Karakter Kümeleri.

Bu tür WinNT.h dosyasında aşağıdaki şekilde bildirilmiştir:

typedef CONST WCHAR *LPCWSTR;

HDC

Bir aygıt içeriğine bir tanıtıcı (DC).

Bu tür WinDef.h dosyasında aşağıdaki şekilde bildirilmiştir:

typedef HANDLE HDC;

0

Bu sorunun bir süre önce sorulduğunu biliyorum ve doğrudan asıl soruyu doğrudan cevaplamaya çalışmıyorum, ancak bu Q / A'nın gelecek okuyucular için biraz eklemek istediğim iyi bir derecesi var. Bu, onları daha iyi Win32 API typedefsve nasıl anlayacağımızla ilgili.

Herhangi biri 32bit makinelerin Windows 95 ve Windows 7-8 dönemleri boyunca herhangi bir Windows programlaması yapmışsa, Win32 APIbunun yüklü typedefsolduğunu, fonksiyonlarının ve yapılarının çoğunun doldurulacağını ve bunların doldurulacağını biliyor ve biliyorlar. kullanılan ağır onlara güveniyordu.


İşte bir gösteri olarak vermek için temel bir windows programı.

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

Bu, bir windows uygulamasını oluşturmak için yeterli kod. Bu temel bir pencere işlemek için çıplak asgari özelliklere başlatmak için en temel kurulum ve gördüğünüz gibi kendisiyle zaten yüklenir typedefsdan Win32 api.


WinMainVe InitWindowsAppfonksiyonlarına bakarak onu parçalayalım : İlk şey, fonksiyonların parametreleri HINSTANCEve PSTR:

WinMaintek bir HINSTANCEnesneyi InitWindowsAppkabul ederken , iki HINSTANCEnesneyi bir PSTR nesnesi veya başka bir typedefdize ve int olarak kabul eder .

InitWindowsAppBuradaki fonksiyonu kullanacağım çünkü her iki fonksiyondaki nesnenin bir tanımını verecek.

Önce HINSTANCEbir şekilde tanımlanır , H , bir üzere andle DERECE ve en yaygın olarak uygulama için kullanılan bir maddedir. İkincisi, artık nadiren kullanılan HANDLEbir Önceki INSTANCE için başka . WinMain()Süreç içerisinde halihazırda mevcut olan pek çok uygulamayı kıracak fonksiyon imzasını değiştirmek zorunda kalmamak için eski amaçlarla tutuldu . Üçüncü parametre a, p , bir ile ointer STR ing.

Bu yüzden bir şeydir canlarından sormak gerekir HANDLE? Win32 APIBurada bulunan belgelere bakarsak : Windows Veri Türleri'ni kolayca arayabilir ve şöyle tanımlanmış olduğunu görebiliriz:

Bir nesneye tanıtıcı. Bu tür WinNT.h dosyasında aşağıdaki şekilde bildirilmiştir:

typedef PVOID HANDLE; 

Şimdi bir tane daha var typedef. Bir PVOIDnedir? Belli ki açık olmalı ama aynı tabloya bakalım ...

Herhangi bir tür için bir işaretçi. Bu WinNT.h bildirilir

typedef void *PVOID;

A HANDLE, aşağıdaki Win32 APIgibi şeylerde birçok nesne bildirmek için kullanılır :

  • HKEY - Bir kayıt defteri anahtarının tanıtıcısı. WinDef.h başlık sayfası
    • typdef HANDLE HKEY;
  • HKL - Bir yerel ayar tanımlayıcısının tanıtıcısı. WinDef.h başlık sayfası
    • typdef HANDLE HKL;
  • HMENU - Bir menüye giderken. WinDef.h başlık sayfası
    • typdef HANDLE HMENU;
  • HPEN - Kaleme bir tutamaç. WinDef.h başlık sayfası
    • typedef HANDLE HPEN;
  • HWND - Bir pencereye tanıtıcı. WinDef.h başlık sayfası
    • typedef HANDLE HWND;
  • ... ve benzeri gibi HBRUSH, HCURSOR, HBITMAP, HDC, HDESK, vb

Bunlar hepsi typedefsbir kullanılarak deklare olduğu typedefbir olan HANDLEve HANDLEkendisi kadar bildirilmiş bir typedefbir gelen PVOIDde olan typedefbir etmek void pointer.


Yani söz konusu olduğunda bunu LPCTSTRaynı dokümanda bulabiliriz:

Bu gibi tanımlanmıştır LPCWSTR, eğer UNICODEtanımlanmıştır ya da bir olduğu LPCSTR, aksi.

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

Yani umarım bu kullanımlarını anlamak için nasıl bir rehber olarak yardımcı olacaktır typedefs, özellikle birlikte Windows Veri Türleri bulunabilir Win32 API.


Makroyu HANDLEetkinleştirirseniz, tanıtıcı türlerinin çoğu yalnızca takma ad olduğundan daha güçlü bir şekilde yazılır STRICT. Yeni projelerde varsayılanın hangisi olduğunu düşünüyorum.
Sebastian Redl

@SebastianRedl Olabilir; Ancak, API'nin çok derinliğine ve dilin kuvvetle yazılmış yönlerinin katılığına girmeye çalışmıyordum. Typedefs kullanımıyla Win32 API ve Veri Tiplerine genel bir bakış daha ...
Francis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.