สิ่งที่เป็นLPCTSTRและLPCTSTRเหมือน (เช่นHDC) และสิ่งที่มันไม่ยืน?
LPCSTR p, q; const char *p, *q;คุณปฏิเสธที่จะใช้มันได้หรือไม่?
สิ่งที่เป็นLPCTSTRและLPCTSTRเหมือน (เช่นHDC) และสิ่งที่มันไม่ยืน?
LPCSTR p, q; const char *p, *q;คุณปฏิเสธที่จะใช้มันได้หรือไม่?
คำตอบ:
การอ้างอิง Brian Kramer ในฟอรัม MSDN
LPCTSTR= Lอ่องP ointer กับC onst T CHAR STRไอเอ็นจี (ไม่ต้องกังวลตัวชี้ยาวเป็นเช่นเดียวกับตัวชี้. มีสองรสชาติของตัวชี้อยู่ภายใต้หน้าต่าง 16 บิต.)นี่คือตาราง:
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 ซึ่งขาดการใช้งานฟังก์ชั่น unicode จำนวนมากคุณไม่จำเป็นต้องใช้เวอร์ชัน ANSI หากคุณกำหนดเป้าหมายเป็น Windows 9x คุณสามารถใช้ TCHAR เพื่อสร้างไบนารี ansi และ unicode จาก codebase เดียวกันตราบใดที่รหัสของคุณไม่มีข้อสันนิษฐานเกี่ยวกับ TCHAR ว่าเป็น char หรือ wchar
หากคุณไม่สนใจ Windows 9x ฉันขอแนะนำให้กำหนดค่าโครงการของคุณเป็น Unicode และใช้ TCHAR เหมือนกับ WCHAR คุณสามารถใช้ฟังก์ชั่น W และประเภทอย่างชัดเจนหากคุณต้องการ แต่ตราบใดที่คุณไม่ได้วางแผนที่จะรันโครงการของคุณบน Windows 9x มันไม่สำคัญเลย
ประเภทเหล่านี้มีการบันทึกไว้ที่Windows Data Typesบน MSDN:
LPCTSTR
LPCWSTRถ้าUNICODEมีการกำหนดเป็นLPCSTRอย่างอื่น สำหรับข้อมูลเพิ่มเติมดูประเภทข้อมูลของ Windows สำหรับสตริงประเภทนี้มีการประกาศใน WinNT.h ดังนี้
#ifdef UNICODE typedef LPCWSTR LPCTSTR; #else typedef LPCSTR LPCTSTR; #endif
LPCWSTRตัวชี้ไปยังสายอักขระที่สิ้นสุดด้วยค่าคงที่ null อักขระ 16 บิต Unicode สำหรับข้อมูลเพิ่มเติมดูชุดอักขระที่ใช้โดยแบบอักษร
ประเภทนี้มีการประกาศใน WinNT.h ดังนี้
typedef CONST WCHAR *LPCWSTR;
HDCหมายเลขอ้างอิงของบริบทอุปกรณ์ (DC)
ประเภทนี้มีการประกาศใน WinDef.h ดังนี้:
typedef HANDLE HDC;
ฉันรู้ว่าคำถามนี้ถูกถามเมื่อไม่นานมานี้และฉันไม่ได้พยายามตอบคำถามต้นฉบับโดยตรง แต่เนื่องจาก Q / A นี้มีคะแนนที่เหมาะสมฉันต้องการเพิ่มอีกเล็กน้อยสำหรับผู้อ่านในอนาคต สิ่งนี้ต้องทำเพิ่มเติมโดยเฉพาะกับ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 นี่คือการตั้งค่าขั้นพื้นฐานที่สุดในการเริ่มต้นคุณสมบัติที่น้อยที่สุดเปลือยเพื่อแสดงหน้าต่างขั้นพื้นฐานและในขณะที่คุณสามารถเห็นมันจะเต็มไปแล้วกับการจากtypedefsWin32 api
ลองแยกย่อยโดยดูที่WinMainและInitWindowsAppฟังก์ชั่น: สิ่งแรกคือพารามิเตอร์ของฟังก์ชั่นHINSTANCEและPSTR:
WinMainยอมรับHINSTANCEวัตถุเดียวในขณะที่InitWindowsAppยอมรับHINSTANCEวัตถุสองชิ้นเป็นวัตถุ PSTR หรือtypedefสตริงอื่นและ int
ฉันจะใช้InitWindowsAppฟังก์ชั่นที่นี่เพราะมันจะให้คำอธิบายของวัตถุในทั้งสองฟังก์ชั่น
อันแรกHINSTANCEถูกกำหนดให้เป็นH andle กับINSTANCEและนี่คืออันที่ใช้กันมากที่สุดสำหรับแอปพลิเคชัน คนที่สองเป็นอีกหนึ่งHANDLEไปก่อนหน้านี้เช่นที่ไม่ค่อยถูกนำมาใช้อีกต่อไป มันถูกเก็บไว้รอบ ๆ เพื่อวัตถุประสงค์ดั้งเดิมเพื่อไม่ต้องเปลี่ยนWinMain()ลายเซ็นฟังก์ชันที่จะทำลายแอปพลิเคชันที่มีอยู่แล้วจำนวนมากในกระบวนการ พารามิเตอร์ที่สามคือP ointer ถึงSTR ing
ดังนั้นเราต้องถามตัวเองว่าอะไรคือ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ที่มีการประกาศใช้typedefซึ่งเป็นHANDLEและHANDLEตัวเองจะถูกประกาศเป็นtypedefจากPVOIDที่นี้ยังเป็นไปtypedefvoid pointer
ดังนั้นเมื่อพูดถึงLPCTSTRเราจะพบว่าในเอกสารเดียวกัน:
มันถูกกำหนดให้เป็น
LPCWSTRถ้าUNICODEมีการกำหนดหรือLPCSTRมิฉะนั้น
#ifdef UNICODE
typedef LPCWSTR LPCSTR;
#else
typedef LPCSTR LPCTSTR;
#endif
เพื่อหวังว่านี้จะช่วยเป็นแนวทางที่จะเป็นวิธีที่จะเข้าใจความหมายของtypedefsโดยเฉพาะอย่างยิ่งกับประเภทของ Windows ข้อมูลWin32 APIที่สามารถพบได้ใน
HANDLEนามแฝงหากคุณเปิดใช้งานSTRICTแมโคร ซึ่งเป็นค่าเริ่มต้นในโครงการใหม่ฉันคิดว่า