LPCTSTRとは何ですか?


37

何であるLPCTSTRLPCTSTR(例えば様HDC)、何それはの略ですか?



3
これが、マイクロソフトが大好きな理由です。
-zxcdw

2
それらの「タイプ」は、例えば、あなたがそうLPCSTR p, q;したいとき、あなたが望んでいたとき、常に驚きを示しますconst char *p, *q;。それらの使用を拒否できますか?
ott--


2
32ビット・アプリケーションは、そのような用語の知識を必要とする64ビットの移植
overexchange

回答:


76

MSDNフォーラムで Brian Kramer 引用

LPCTSTR= L・オングPのにointer C onst T CHAR STR INGの(ない心配は、長いポインタはポインタと同じである。ポインタの2種類が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)
ドナルフェローズ

2
いつこの種のポインターを使用する必要がありますか?
フロリアンマーゲイン

@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/en-us/library/windows/desktop/ms645511(v = vs.85).aspx

多くのUnicode関数の実装が欠けているWindows 9xをターゲットにしている場合を除き、ANSIバージョンを使用する必要はありません。Windows 9xを対象としている場合、TCHARがcharまたはwcharであるかどうかをコードが仮定しない限り、TCHARを使用して同じコードベースからANSIおよびUnicodeバイナリを構築できます。

Windows 9xを気にしない場合は、プロジェクトをUnicodeとして構成し、TCHARをWCHARと同じものとして扱うことをお勧めします。必要に応じて、Wの関数と型を明示的に使用できますが、Windows 9xでプロジェクトを実行する予定がない限り、それは実際には重要ではありません。


0

これらのタイプは、MSDNのWindowsデータタイプに記載されています

LPCTSTR

AnがLPCWSTRあればUNICODE、定義されているLPCSTRそう。詳細については、「文字列のWindowsデータ型」を参照してください。

このタイプは、WinNT.hで次のように宣言されています。

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

LPCWSTR

16ビットUnicode文字のnullで終わる定数文字列へのポインター。詳細については、「フォントで使用される文字セット」を参照してください。

このタイプは、WinNT.hで次のように宣言されています。

typedef CONST WCHAR *LPCWSTR;

HDC

デバイスコンテキスト(DC)へのハンドル。

このタイプは、WinDef.hで次のように宣言されます。

typedef HANDLE HDC;

0

私はこの質問がかなり前に尋ねられたことを知っており、私は元の正確な質問に直接答えようとはしていませんが、この特定のQ / Aには適切な評価があるので、将来の読者のためにここに少し追加したいと思います。これは、より具体的に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ます。


関数WinMainInitWindowsApp関数を見て、分解してみましょう。まず、関数のパラメーターHINSTANCEPSTR

WinMain1つのHINSTANCEオブジェクトをInitWindowsApp受け入れ、2つのHINSTANCEオブジェクト、PSTRオブジェクトまたはその他のtypedef文字列とint を受け入れます。

InitWindowsApp両方の関数でオブジェクトの説明を提供するため、ここで関数を使用します。

1つ目HINSTANCEは、INSTANCEに対するH andle として定義され、これはアプリケーションで最も一般的に使用されるものです。2つ目は、以前はほとんど使用されていなかった以前のインスタンスの別のインスタンスです。これは、変更する必要がないようにするために、従来の目的のために周りに維持した過程で、多くの既存のアプリケーションを壊す関数のシグネチャを。第三のパラメータであるPのにointer STRの ING。HANDLEWinMain()

だから、私たちは自分自身に何を尋ねる必要がありHANDLEますか?私たちが見るとWin32 APIドキュメントここで見つける:Windowsのデータ型は、我々は簡単にそれを見て、それは次のように定義されていることがわかります。

オブジェクトへのハンドル。このタイプは、WinNT.hで次のように宣言されています。

typedef PVOID HANDLE; 

もう1つあり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であるとHANDLEし、HANDLEそれ自身は次のように宣言されているtypedefからPVOIDでもあるtypedefvoid pointer


したがってLPCTSTR、同じドキュメントでそれを見つけることができます:

LPCWSTRif UNICODEが定義されているか、LPCSTRそうでなければ定義されています。

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

したがって、これが、typedefs特ににあるWindowsデータ型の使用を理解する方法についてのガイドとして役立つことを願っていWin32 APIます。


ハンドルタイプの多くは、マクロHANDLEをアクティブにした場合、単なるエイリアスよりも強く型付けされますSTRICT。これは新しいプロジェクトのデフォルトです。
セバスチャンレッド

@SebastianRedl可能性があります。しかし、私はAPIの深さと、言語の厳密に型指定された側面の厳密さを追求しようとしていませんでした。typedefを使用したWin32 APIとそのデータ型の概要です...
Francis Cugler
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.