এলপিসিটিএসটি কী?


37

কী LPCTSTRএবং LPCTSTRমত (উদাহরণস্বরূপ HDC) এবং এটি কি জন্য দাঁড়ায়?



3
এই কারণেই আমরা কেবল মাইক্রোসফ্টকে ভালবাসি।
zxcdw

2
এই "প্রকারগুলি" সর্বদা অবাক করে তোলে, উদাহরণস্বরূপ আপনি যখন করেন LPCSTR p, q;এবং আপনি কী করতে চান const char *p, *q;। আপনি তাদের ব্যবহার অস্বীকার করতে পারেন?
অট--

9
একটি ঘৃণা।
টমাস এডিং

2
32-বিট অ্যাপ্লিকেশনটির 64 বিট পোর্টিংয়ের জন্য এ জাতীয় পরিভাষাগুলির জ্ঞান প্রয়োজন
2-15

উত্তর:


76

এমএসডিএন ফোরামে ব্রায়ান ক্র্যামারের উদ্ধৃতি দেওয়া হচ্ছে

LPCTSTR= এল Ong পি একটি থেকে ointer সি onst টি CHAR STR ing (চিন্তা করবেন না, একটি দীর্ঘ পয়েন্টার একটি পয়েন্টার হিসাবে একই। সেখানে 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 বিটিডাব্লু)
ডোনাল ফেলো

2
তখন আমি কখন এই জাতীয় পয়েন্টার ব্যবহার করব?
ফ্লোরিয়ান মার্জাইন

@ ফ্লোরিয়ানমার্গাইন যখন কোনও এপিআই আপনাকে বলে। ততক্ষণ কেবল 'যথাযথ' প্রকারগুলি ব্যবহার করুন
জেমস

1
সতর্কতা অবলম্বন করুন, এখানে সচেতন হওয়ার মতো প্রচুর সতর্কতা রয়েছে। wchar_t একটি 16 বিট টাইপ, তবে ucs2 এবং utf-16 এনকোডযুক্ত ইউনিকোড অক্ষর উভয়ই সংরক্ষণ করতে ব্যবহৃত হতে পারে। utf-16 একক অক্ষরকে এনকোড করতে একাধিক wchar_t ব্যবহার করতে পারে, ucs2 কেবল ইউনিকোড অক্ষরগুলির একটি উপসেট সমর্থন করে। কোন এপিআই ফাংশনগুলি আপনাকে কল করতে হবে তা ব্যবহৃত এনকোডিংয়ের উপরও নির্ভর করে।
মাইকেল শ

2

6

টিসিএইচএআর সম্পর্কিত কোনও প্রকারের ব্যবহার করার দরকার নেই।

এই প্রকারগুলি, সমস্ত কাঠামোর ধরণের যা সেগুলি ব্যবহার করে এবং সম্পর্কিত সমস্ত ফাংশন একটি এএনএসআই বা ইউনিকোড সংস্করণে (আপনার প্রকল্পের কনফিগারেশনের উপর ভিত্তি করে) সংকলন করার সময় ম্যাপ করা হয়। এএনএসআই সংস্করণগুলিতে সাধারণত নামের শেষে একটি এ সংযুক্ত থাকে এবং ইউনিকোড সংস্করণগুলিতে একটি ডাব্লু যুক্ত হয় you আপনি যদি পছন্দ করেন তবে আপনি এগুলি স্পষ্টভাবে ব্যবহার করতে পারেন। এমএসডিএন যখন প্রয়োজন তখন এটি নোট করবে, উদাহরণস্বরূপ এটি এখানে একটি বার্তাবক্সআইন্ডারেক্টএ এবং মেসেজবক্সআইড্রেইট ফাংশন তালিকাভুক্ত করে: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx

আপনি যদি উইন্ডোজ 9 এক্সকে লক্ষ্য না করে থাকেন, যার অনেকগুলি ইউনিকোড ফাংশন বাস্তবায়নের অভাব হয়, এএনএসআই সংস্করণ ব্যবহার করার দরকার নেই। যদি আপনি উইন্ডোজ 9 এক্স টার্গেট করে থাকেন তবে আপনি TCHAR ব্যবহার করে একই কোডবেস থেকে অ্যানসি এবং ইউনিকোড বাইনারি তৈরি করতে পারবেন, যতক্ষণ না আপনার কোড টিসিএইচআরটি চর বা উইচার কিনা তা নিয়ে কোনও অনুমান করে না।

আপনি যদি উইন্ডোজ 9 এক্স সম্পর্কে চিন্তা না করেন তবে আমি আপনার প্রকল্পটি ইউনিকোড হিসাবে কনফিগার করতে এবং টিসিএইচএআরকে ডাব্লুসিএইচএর অনুরূপ হিসাবে বিবেচনা করার পরামর্শ দিচ্ছি। আপনি যদি পছন্দ করেন তবে আপনি ডাব্লু ফাংশন এবং প্রকারগুলি স্পষ্টভাবে ব্যবহার করতে পারেন, তবে যতক্ষণ না আপনি উইন্ডোজ 9x এ আপনার প্রকল্পটি চালানোর পরিকল্পনা করেন না, ততক্ষণ তা আসলে কিছু যায় আসে না।


0

এই ধরনেরগুলি উইন্ডোজ ডেটা টাইপগুলিতে এমএসডিএন তে নথিভুক্ত করা হয় :

LPCTSTR

একটি LPCWSTRযদি UNICODEসংজ্ঞায়িত হয়, LPCSTRঅন্যথায়। আরও তথ্যের জন্য, স্ট্রিংগুলির জন্য উইন্ডোজ ডেটা প্রকারগুলি দেখুন।

এই ধরণেরটি WinNT.h এ নিম্নলিখিত হিসাবে ঘোষণা করা হয়েছে:

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

LPCWSTR

16-বিট ইউনিকোড অক্ষরের স্থির নাল-টার্মিনেটেড স্ট্রিংয়ের পয়েন্টার। আরও তথ্যের জন্য, হরফ দ্বারা ব্যবহৃত অক্ষর সেটগুলি দেখুন।

এই ধরণেরটি WinNT.h এ নিম্নলিখিত হিসাবে ঘোষণা করা হয়েছে:

typedef CONST WCHAR *LPCWSTR;

HDC

একটি ডিভাইস প্রসঙ্গে হ্যান্ডেল (ডিসি)।

এই ধরণেরটি WinDef.h এ নিম্নলিখিত হিসাবে ঘোষণা করা হয়েছে:

typedef HANDLE HDC;

0

আমি জানি যে এই প্রশ্নটি বেশ কিছু সময় আগে জিজ্ঞাসা করা হয়েছিল এবং আমি সরাসরি আসল প্রশ্নের সরাসরি উত্তর দেওয়ার চেষ্টা করছি না, তবে এই নির্দিষ্ট প্রশ্ন / এটির একটি সুনির্দিষ্ট রেটিং রয়েছে বলে আমি ভবিষ্যতের পাঠকদের জন্য এখানে কিছুটা যুক্ত করতে চাই। এটি Win32 API typedefsকীভাবে তাদের বোঝা যায় সে সম্পর্কে আরও সুনির্দিষ্টভাবে করতে হবে ।

উইন্ডোজ 95 থেকে 32 বিট মেশিনগুলির যুগে এবং উইন্ডোজ --8 পর্যন্ত কেউ যদি কোনও উইন্ডোজ প্রোগ্রামিং করেন তবে তারা বুঝতে এবং জেনে নিতে পারে যে এটি Win32 APIলোড হয়েছে typedefsএবং তাদের বেশিরভাগ কার্যাদি এবং কাঠামো যা পূরণ করতে হবে এবং তাদের উপর প্রচুর নির্ভর।


এখানে একটি বিক্ষোভ হিসাবে দেওয়ার জন্য একটি উইন্ডোজ প্রোগ্রাম রয়েছে।

#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;
}

উইন্ডোজ অ্যাপ্লিকেশন রেন্ডার করার জন্য এটি সবেমাত্র যথেষ্ট কোড। একটি বেসিক উইন্ডো রেন্ডার করতে খালি ন্যূনতম বৈশিষ্ট্যগুলি আরম্ভ করার জন্য এটি সবচেয়ে বেসিক সেটআপ এবং আপনি দেখতে পাচ্ছেন এটি ইতিমধ্যে এর typedefsথেকে লোড হয়েছে Win32 api


এর WinMainএবং InitWindowsAppফাংশনগুলি দেখে এটি ভেঙে ফেলা যাক : প্রথম জিনিসটি হ'ল ফাংশনগুলির পরামিতি HINSTANCEএবং PSTR:

WinMainদুটি বস্তু পিএসআরটি অবজেক্ট বা অন্য কোনও স্ট্রিং এবং কোন ইনট গ্রহণ করার HINSTANCEসময় একটি একক বস্তু InitWindowsAppগ্রহণ করে HINSTANCEacceptypedef

আমি InitWindowsAppএখানে ফাংশনটি ব্যবহার করব কারণ এটি উভয় ফাংশনে অবজেক্টের বিবরণ দেবে।

প্রথমটি একটি ইনস্ট্যান্সের এইচ অ্যান্ডেল HINSTANCEহিসাবে সংজ্ঞায়িত করা হয় এবং এটি হ'ল অ্যাপ্লিকেশনটির জন্য সর্বাধিক ব্যবহৃত হয়। দ্বিতীয়টি পূর্বের ইনস্ট্যান্টের আরেকটি যা খুব কমই ব্যবহৃত হয়। প্রক্রিয়াটিতে ইতিমধ্যে বিদ্যমান অনেকগুলি অ্যাপ্লিকেশন ভেঙে ফাংশনের স্বাক্ষরটি পরিবর্তন করতে না পারার জন্য এটি উত্তরাধিকারের উদ্দেশ্যে রাখা হয়েছিল । তৃতীয় প্যারামিটারটি হল পি একটি থেকে ointer STR ING।HANDLEWinMain()

সুতরাং আমরা আমাদের নিজের থেকে জিজ্ঞাসা করতে হয় একটি কি HANDLE? আমরা যদি Win32 APIএখানে পাওয়া নথিগুলিতে নজর রাখি : উইন্ডোজ ডেটা প্রকারগুলি আমরা সহজেই এটি সন্ধান করতে পারি এবং দেখতে পারি যে এটি সংজ্ঞায়িত হয়েছে:

একটি বস্তুর একটি হ্যান্ডেল। এই ধরণেরটি WinNT.h এ নিম্নলিখিত হিসাবে ঘোষণা করা হয়েছে:

typedef PVOID HANDLE; 

এখন আমাদের আরেকটি আছে typedef। একটি কি PVOID? ভাল এটি সুস্পষ্ট হওয়া উচিত তবে একই টেবিলে এটি দেখতে দিন ...

যে কোনও ধরণের পয়েন্টার। এটি WinNT.h. এ ঘোষণা করা হয়েছে

typedef void *PVOID;

একজন HANDLEঅনেক বস্তু ঘোষণা করতে ব্যবহৃত হয় Win32 APIযেমন জিনিস:

  • HKEY - একটি রেজিস্ট্রি কীতে একটি হ্যান্ডেল। উইনডেফ
    • typdef HANDLE HKEY;
  • HKL - একটি স্থানীয় শনাক্তকারীকে একটি হ্যান্ডেল। উইনডেফ
    • typdef HANDLE HKL;
  • HMENU - একটি মেনুতে একটি হ্যান্ডেল। উইনডেফ
    • typdef HANDLE HMENU;
  • HPEN - একটি কলমের হাতল উইনডেফ
    • typedef HANDLE HPEN;
  • HWND - একটি উইন্ডো একটি হ্যান্ডেল। উইনডেফ
    • typedef HANDLE HWND;
  • ... এবং তাই যেমন HBRUSH, HCURSOR, HBITMAP, HDC, HDESK, ইত্যাদি

এই সব হয় typedefsযে একটি ব্যবহার ঘোষিত হয় typedefযা হয় HANDLEএবং HANDLEনিজেই হিসেবে ঘোষণা করা হয় typedefA থেকে PVOIDযা একটি হল typedefএকটি থেকে void pointer


সুতরাং যখন এটি আসে LPCTSTRআমরা একই ডক্সে এটি খুঁজে পেতে পারি:

এটি সংজ্ঞায়িত হিসাবে LPCWSTRযদি UNICODEসংজ্ঞায়িত হয় বা LPCSTRঅন্যথায়।

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

সুতরাং আশা করা যায় যে typedefsএটি বিশেষত উইন্ডোজ ডেটা টাইপগুলির মধ্যে কীভাবে পাওয়া যাবে সেগুলির ব্যবহারগুলি কীভাবে বোঝা যায় সে সম্পর্কে একটি গাইড হিসাবে সহায়তা করবে Win32 API


হ্যান্ডেল ধরণের অনেকগুলি ম্যাক্রো HANDLEসক্রিয় করা হলে কেবলমাত্র এলিয়াস হওয়ার চেয়ে বেশি শক্তভাবে টাইপ করা হয় STRICT। নতুন প্রকল্পে কোনটি ডিফল্ট, আমার ধারণা।
সেবাস্তিয়ান রেডল

@ সেবাস্তিয়ানআরডেল এটি হতে পারে; তবে আমি এপিআই এবং গভীরতার সাথে ভাষার দৃ typ়ভাবে টাইপ করা দিকগুলির কঠোরতার খুব গভীরতায় যাওয়ার চেষ্টা করছিলাম না। এটি টাইপডেফস ব্যবহার করে উইন
ফ্রান্সিস কিগ্রার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.