LPCTSTR= L ong P ointer a um C onst
T CHAR STR ing (não se preocupa, um ponteiro longo é o mesmo que um ponteiro. Houve dois sabores de ponteiros sob janelas de 16 bits).
Aqui está a tabela:
LPSTR = char*
LPCSTR = const char*
LPWSTR = wchar_t*
LPCWSTR = const wchar_t*
LPTSTR= char* or wchar_t*dependendo de_UNICODE
LPCTSTR= const char* or const wchar_t*dependendo de_UNICODE
Toda vez que vejo esse nome, sinto vontade de me encolher. Há algo sobre isso que me deixa desconfortável. (+1 BTW)
Donal Fellows
2
Quando devo usar esse tipo de ponteiro?
Florian Margaine
@FlorianMargaine Quando uma API diz para você. Basta usar os tipos 'apropriados' até então #
James
1
esteja avisado, há muitas advertências aqui. O wchar_t é do tipo 16 bits, mas pode ser usado para armazenar caracteres unicode codificados em ucs2 e utf-16. O utf-16 pode usar vários wchar_t para codificar uma única letra, o ucs2 suporta apenas um subconjunto do conjunto de caracteres unicode. Quais funções da API você precisa chamar também dependem da codificação usada.
Michael Shaw
2
O pior é DWORD, que costumava ser uma palavra dupla de 32 bits, mas hoje é uma meia palavra de 32 bits :-)
gnasher729
6
Não é necessário usar nenhum dos tipos relacionados ao TCHAR.
Esses tipos, todos os tipos de estrutura que os utilizam e todas as funções relacionadas são mapeadas em tempo de compilação para uma versão ANSI ou UNICODE (com base na configuração do seu projeto). As versões ANSI normalmente têm um A anexado ao final do nome e as versões unicode anexam um W. Você pode usá-las explicitamente, se preferir. O MSDN observará isso quando necessário, por exemplo, lista uma função MessageBoxIndirectA e MessageBoxIndirectW aqui: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx
A menos que você esteja direcionando o Windows 9x, que carecia de implementações de muitas funções unicode, não há necessidade de usar as versões ANSI. Se você estiver direcionando o Windows 9x, poderá usar o TCHAR para criar um binário ansi e unicode a partir da mesma base de código, desde que o seu código não faça suposições sobre se o TCHAR é um caractere ou um wchar.
Se você não se importa com o Windows 9x, recomendo configurar seu projeto como unicode e tratar o TCHAR como idêntico ao WCHAR. Você pode usar explicitamente as funções e os tipos W, se preferir, mas desde que não planeje executar seu projeto no Windows 9x, isso realmente não importa.
Um ponteiro para uma cadeia constante terminada por nulo constante de caracteres Unicode de 16 bits. Para mais informações, consulte Conjuntos de caracteres usados por fontes.
Este tipo é declarado no WinNT.h da seguinte maneira:
Sei que essa pergunta foi feita há algum tempo e não estou tentando responder diretamente à pergunta original exata, mas como essa pergunta / pergunta específica tem uma classificação decente, gostaria de adicionar um pouco aqui para futuros leitores. Isso tem a ver mais especificamente com o Win32APItypedefse como entendê-los.
Se alguém já fez alguma programação do Windows durante a era das máquinas de 32 bits, do Windows 95 até o Windows 7-8, ele entende e sabe que ele Win32APIestá carregado typedefse que a maioria de suas funções e estruturas devem ser preenchidas e usado dependem fortemente deles.
Aqui está um programa básico do Windows para dar como demonstração.
Este é apenas um código suficiente para renderizar um aplicativo do Windows. Essa é a configuração mais básica para inicializar as propriedades mínimas vazias para renderizar uma janela básica e, como você pode ver, ela já está carregada typedefsno Win32api.
Vamos analisar detalhadamente as funções WinMaine InitWindowsApp: a primeira coisa são os parâmetros das funções HINSTANCEe PSTR:
WinMainaceita um único HINSTANCEobjeto enquanto InitWindowsAppaceita dois HINSTANCEobjetos, um objeto PSTR ou alguma outra typedefstring e um int.
Usarei a InitWindowsAppfunção aqui, pois ela fornecerá uma descrição do objeto nas duas funções.
O primeiro HINSTANCEé definido como um H andle para um INSTANCE e esse é o mais usado para o aplicativo. O segundo é outro HANDLEde uma Instância Anterior que raramente é mais usada. Foi mantido para fins legados para não precisar alterar a WinMain()assinatura da função que quebraria muitos aplicativos já existentes no processo. O terceiro parâmetro é um P ointer para uma STR ing.
Então temos que perguntar a nós mesmos o que é um HANDLE? Se procurarmos nos Win32APIdocumentos encontrados aqui: Tipos de dados do Windows , podemos consultá-lo facilmente e ver se ele está definido como:
Um identificador para um objeto. Este tipo é declarado no WinNT.h da seguinte maneira:
typedef PVOID HANDLE;
Agora temos outro typedef. O que é um PVOID? Bem, deve ser óbvio, mas vamos procurar isso na mesma tabela ...
Um ponteiro para qualquer tipo. Isso é declarado no WinNT.h
typedefvoid*PVOID;
A HANDLEé usado para declarar muitos objetos Win32API, como:
HKEY - Um identificador para uma chave do registro. Declarado em WinDef.h
typdef HANDLE HKEY;
HKL - Um identificador para um identificador de localidade. Declarado em WinDef.h
typdef HANDLE HKL;
HMENU - Uma alça para um menu. Declarado em WinDef.h
typdef HANDLE HMENU;
HPEN - Uma alça para uma caneta. Declarado em WinDef.h
typedef HANDLE HPEN;
HWND - Uma alça para uma janela. Declarado em WinDef.h
typedef HANDLE HWND;
... e assim por diante, como HBRUSH, HCURSOR, HBITMAP, HDC, HDESK, etc.
Estes são todos os typedefsque são declarados usando a typedefque é a HANDLEe o HANDLEpróprio é declarado como a typedefde a PVOIDque também é a typedefpara a void pointer.
Então, quando se trata de LPCTSTR, podemos encontrar isso nos mesmos documentos:
É definido como um LPCWSTRse UNICODEestá definido ou de LPCSTRoutra forma.
Espero que isso ajude como um guia sobre como entender os usos de typedefsespecialmente com os tipos de dados do Windows que podem ser encontrados no Win32API.
Muitos dos tipos de identificador são mais fortemente digitados do que apenas serem HANDLEaliases se você ativar a STRICTmacro. Qual é o padrão em novos projetos, eu acho.
Sebastian Redl
@SebastianRedl Poderia ser; mas não estava tentando me aprofundar muito na API e no rigor dos aspectos fortemente tipados da linguagem. Era mais uma visão geral da API do Win32 e de seus tipos de dados pelo uso de typedefs ...
LPCSTR p, q;
e queria terconst char *p, *q;
. Você pode se recusar a usá-los?Respostas:
Citando Brian Kramer nos fóruns do MSDN
fonte
Não é necessário usar nenhum dos tipos relacionados ao TCHAR.
Esses tipos, todos os tipos de estrutura que os utilizam e todas as funções relacionadas são mapeadas em tempo de compilação para uma versão ANSI ou UNICODE (com base na configuração do seu projeto). As versões ANSI normalmente têm um A anexado ao final do nome e as versões unicode anexam um W. Você pode usá-las explicitamente, se preferir. O MSDN observará isso quando necessário, por exemplo, lista uma função MessageBoxIndirectA e MessageBoxIndirectW aqui: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx
A menos que você esteja direcionando o Windows 9x, que carecia de implementações de muitas funções unicode, não há necessidade de usar as versões ANSI. Se você estiver direcionando o Windows 9x, poderá usar o TCHAR para criar um binário ansi e unicode a partir da mesma base de código, desde que o seu código não faça suposições sobre se o TCHAR é um caractere ou um wchar.
Se você não se importa com o Windows 9x, recomendo configurar seu projeto como unicode e tratar o TCHAR como idêntico ao WCHAR. Você pode usar explicitamente as funções e os tipos W, se preferir, mas desde que não planeje executar seu projeto no Windows 9x, isso realmente não importa.
fonte
Esses tipos estão documentados em Tipos de dados do Windows no MSDN:
fonte
Sei que essa pergunta foi feita há algum tempo e não estou tentando responder diretamente à pergunta original exata, mas como essa pergunta / pergunta específica tem uma classificação decente, gostaria de adicionar um pouco aqui para futuros leitores. Isso tem a ver mais especificamente com o
Win32
API
typedefs
e como entendê-los.Se alguém já fez alguma programação do Windows durante a era das máquinas de 32 bits, do Windows 95 até o Windows 7-8, ele entende e sabe que ele
Win32
API
está carregadotypedefs
e que a maioria de suas funções e estruturas devem ser preenchidas e usado dependem fortemente deles.Aqui está um programa básico do Windows para dar como demonstração.
Este é apenas um código suficiente para renderizar um aplicativo do Windows. Essa é a configuração mais básica para inicializar as propriedades mínimas vazias para renderizar uma janela básica e, como você pode ver, ela já está carregada
typedefs
noWin32
api
.Vamos analisar detalhadamente as funções
WinMain
eInitWindowsApp
: a primeira coisa são os parâmetros das funçõesHINSTANCE
ePSTR
:WinMain
aceita um únicoHINSTANCE
objeto enquantoInitWindowsApp
aceita doisHINSTANCE
objetos, um objeto PSTR ou alguma outratypedef
string e um int.Usarei a
InitWindowsApp
função aqui, pois ela fornecerá uma descrição do objeto nas duas funções.O primeiro
HINSTANCE
é definido como um H andle para um INSTANCE e esse é o mais usado para o aplicativo. O segundo é outroHANDLE
de uma Instância Anterior que raramente é mais usada. Foi mantido para fins legados para não precisar alterar aWinMain()
assinatura da função que quebraria muitos aplicativos já existentes no processo. O terceiro parâmetro é um P ointer para uma STR ing.Então temos que perguntar a nós mesmos o que é um
HANDLE
? Se procurarmos nosWin32
API
documentos encontrados aqui: Tipos de dados do Windows , podemos consultá-lo facilmente e ver se ele está definido como:Agora temos outro
typedef
. O que é umPVOID
? Bem, deve ser óbvio, mas vamos procurar isso na mesma tabela ...A
HANDLE
é usado para declarar muitos objetosWin32
API
, como:HKEY
- Um identificador para uma chave do registro. Declarado em WinDef.htypdef HANDLE HKEY;
HKL
- Um identificador para um identificador de localidade. Declarado em WinDef.htypdef HANDLE HKL;
HMENU
- Uma alça para um menu. Declarado em WinDef.htypdef HANDLE HMENU;
HPEN
- Uma alça para uma caneta. Declarado em WinDef.htypedef HANDLE HPEN;
HWND
- Uma alça para uma janela. Declarado em WinDef.htypedef HANDLE HWND;
HBRUSH
,HCURSOR
,HBITMAP
,HDC
,HDESK
, etc.Estes são todos os
typedefs
que são declarados usando atypedef
que é aHANDLE
e oHANDLE
próprio é declarado como atypedef
de aPVOID
que também é atypedef
para avoid pointer
.Então, quando se trata de
LPCTSTR
, podemos encontrar isso nos mesmos documentos:Espero que isso ajude como um guia sobre como entender os usos de
typedefs
especialmente com os tipos de dados do Windows que podem ser encontrados noWin32
API
.fonte
HANDLE
aliases se você ativar aSTRICT
macro. Qual é o padrão em novos projetos, eu acho.