что 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*зависимости от_UNICODELPCTSTR= в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макрос. Что по умолчанию в новых проектах, я думаю.