что LPCTSTR
и LPCTSTR
как (например HDC
) и что это означает?
LPCSTR p, q;
и вы хотели иметь const char *p, *q;
. Можете ли вы отказаться от их использования?
что LPCTSTR
и LPCTSTR
как (например HDC
) и что это означает?
LPCSTR p, q;
и вы хотели иметь const char *p, *q;
. Можете ли вы отказаться от их использования?
Ответы:
Цитировать Брайана Крамера на форумах MSDN
LPCTSTR
= L Ong P ointer к C onst T CHAR STR Инг (не волнуйтесь, длинный указатель такой же , как указатель. Были две разновидности указателей под 16-битных Windows.)Вот таблица:
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
Нет необходимости использовать какие-либо типы, относящиеся к TCHAR.
Эти типы, все типы структур, которые их используют, и все связанные функции отображаются во время компиляции в версию ANSI или UNICODE (в зависимости от конфигурации вашего проекта). В версиях ANSI обычно к концу имени добавляется буква A, а в версиях Unicode добавляется буква W. Вы можете использовать их явно, если хотите. MSDN заметит это при необходимости, например, перечисляет функции MessageBoxIndirectA и MessageBoxIndirectW здесь: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx
Если вы не нацелены на Windows 9x, в которой отсутствовали реализации многих функций Юникода, нет необходимости использовать версии ANSI. Если вы ориентируетесь на Windows 9x, вы можете использовать TCHAR для создания бинарных файлов ANSI и Unicode из одной и той же кодовой базы, если ваш код не делает предположений о том, является ли TCHAR символом или wchar.
Если вас не волнует Windows 9x, я рекомендую настроить ваш проект как Unicode и рассматривать TCHAR как идентичный WCHAR. Вы можете явно использовать функции и типы W, если хотите, но если вы не планируете запускать свой проект в Windows 9x, это не имеет значения.
Эти типы описаны в разделе Типы данных Windows на MSDN:
LPCTSTR
LPCWSTR
, ЕслиUNICODE
определено, вLPCSTR
противном случае. Для получения дополнительной информации см. Типы данных Windows для строк.Этот тип объявлен в WinNT.h следующим образом:
#ifdef UNICODE typedef LPCWSTR LPCTSTR; #else typedef LPCSTR LPCTSTR; #endif
LPCWSTR
Указатель на постоянную строку с нулевым символом в конце, состоящую из 16-битных символов Юникода. Для получения дополнительной информации см. Наборы символов, используемые шрифтами.
Этот тип объявлен в WinNT.h следующим образом:
typedef CONST WCHAR *LPCWSTR;
HDC
Дескриптор контекста устройства (DC).
Этот тип объявлен в WinDef.h следующим образом:
typedef HANDLE HDC;
Я знаю, что этот вопрос задавался довольно давно, и я не пытаюсь прямо ответить на точный оригинальный вопрос, но, поскольку этот конкретный вопрос / ответ имеет достойную оценку, я хотел бы добавить сюда немного для будущих читателей. Это связано с тем, Win32
API
typedefs
как и как их понимать.
Если кто-то когда-либо занимался программированием для Windows в эпоху 32-битных машин от Windows 95 до Windows 7-8 и выше, они понимают и знают, что они 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
.
Давайте разорвать его, глядя на WinMain
и InitWindowsApp
функции: Первое , это параметры функций HINSTANCE
и PSTR
:
WinMain
принимает один HINSTANCE
объект, в то время как InitWindowsApp
принимает два HINSTANCE
объекта: объект PSTR или некоторую другую typedef
строку и int.
Я буду использовать InitWindowsApp
функцию здесь, так как она даст описание объекта в обеих функциях.
Первый HINSTANCE
определяется как H andle для INSTANCE, и именно этот наиболее часто используется для приложения. Второй - это другой HANDLE
предыдущий инстанс, который редко используется больше. Он хранился в унаследованных целях, чтобы не приходилось изменять WinMain()
сигнатуру функции, которая может нарушить работу многих уже существующих приложений. Третий параметр является Р ointer к STR Инж.
Итак, мы должны спросить себя, что это 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;
HBRUSH
, HCURSOR
, HBITMAP
, HDC
, HDESK
и т.д.Это все typedefs
, которые объявлены с использованием a, typedef
который является a, HANDLE
а HANDLE
сам по себе объявлен как a typedef
из a, PVOID
который также является a typedef
для a void pointer
.
Поэтому, когда дело доходит до LPCTSTR
нас, мы можем найти это в тех же документах:
Это определяется как
LPCWSTR
еслиUNICODE
определено илиLPCSTR
иначе.
#ifdef UNICODE
typedef LPCWSTR LPCSTR;
#else
typedef LPCSTR LPCTSTR;
#endif
Надеюсь, это поможет вам понять, как использовать typedefs
особенности типов данных Windows, которые можно найти в Win32
API
.
HANDLE
псевдонимы, если вы активируете STRICT
макрос. Что по умолчанию в новых проектах, я думаю.