Win32 API
खिड़कियों से निपटना
खोज…
एक खिड़की का निर्माण
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <tchar.h>
const TCHAR CLSNAME[] = TEXT("helloworldWClass");
LRESULT CALLBACK winproc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp);
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PTSTR cmdline,
int cmdshow)
{
WNDCLASSEX wc = { };
MSG msg;
HWND hwnd;
wc.cbSize = sizeof (wc);
wc.style = 0;
wc.lpfnWndProc = winproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = CLSNAME;
wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, TEXT("Could not register window class"),
NULL, MB_ICONERROR);
return 0;
}
hwnd = CreateWindowEx(WS_EX_LEFT,
CLSNAME,
NULL,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
NULL);
if (!hwnd) {
MessageBox(NULL, TEXT("Could not create window"), NULL, MB_ICONERROR);
return 0;
}
ShowWindow(hwnd, cmdshow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK winproc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
{
return DefWindowProc(hwnd, wm, wp, lp);
}
पहली चीज़ जो देखती है वह है दो स्थूल परिभाषाएँ, UNICODE
और _UNICODE
। ये मैक्रोज़ हमारे कार्यक्रम को व्यापक चरित्र तार ( wchar_t[n]
) को समझने का कारण बनते हैं, न कि सादे संकीर्ण तार ( char[n]
)। नतीजतन, सभी स्ट्रिंग शाब्दिकों को एक TEXT(
मैक्रो में लपेटा जाना चाहिए। Win32 स्ट्रिंग्स के लिए सामान्य वर्ण प्रकार TCHAR
, जिसकी परिभाषा इस बात पर निर्भर करती है कि UNICODE
परिभाषित है या नहीं। एक नया हेडर शामिल है: <tchar.h>
में शामिल है) TCHAR
घोषणा।
एक विंडो में एक विंडो क्लास के रूप में जाना जाता है। यह उस विंडो के बारे में जानकारी का वर्णन करता है, जिसे उसके उदाहरणों, जैसे आइकन, कर्सर और अन्य के बीच साझा किया जाना है। विंडो क्लास नाम से एक विंडो क्लास की पहचान की जाती है, जो इस उदाहरण में CLSNAME
वैश्विक चर में दी गई है। WinMain
का पहला कार्य विंडो क्लास संरचना, WNDCLASSEX wc
को भरना है। सदस्य हैं:
- cbSize: आकार, बाइट्स में, संरचना का
- शैली: खिड़की वर्ग शैली। यह अभी के लिए 0 है।
- lpfnWndProc: यह अधिक महत्वपूर्ण क्षेत्रों में से एक है। यह विंडो प्रक्रिया का पता संग्रहीत करता है। विंडो प्रक्रिया एक फ़ंक्शन है जो सभी विंडो के लिए घटनाओं को संभालती है जो इस विंडो क्लास के उदाहरण हैं।
- cbClsExtra: विंडो क्लास के लिए आवंटित करने के लिए अतिरिक्त बाइट्स की संख्या। अधिकांश स्थितियों के लिए, यह सदस्य 0 है।
- cbWndExtra: प्रत्येक व्यक्तिगत विंडो के लिए आवंटित करने के लिए अतिरिक्त बाइट्स की संख्या। इसे
cbClsExtra
साथ भ्रमित न करें, जो सभी उदाहरणों के लिए सामान्य है। यह अक्सर 0 होता है। - hInstance: इंस्टेंस हैंडल। बस
WinMain
मेंhInst
तर्क को इस क्षेत्र में असाइन करें। - hIcon: विंडो क्लास के लिए आइकन हैंडल।
LoadIcon(NULL, IDI_APPLICATION)
डिफ़ॉल्ट एप्लिकेशन आइकन को लोड करता है। - hCursor: विंडो क्लास के लिए कर्सर हैंडल।
LoadCursor(NULL, IDC_ARROW)
डिफ़ॉल्ट कर्सर लोड करता है। - hbrBackground: बैकग्राउंड ब्रश का एक हैंडल।
GetStockObject (WHITE_BRUSH)
एक सफेद ब्रश को संभालता है। रिटर्न वैल्यू डाली जानी चाहिए क्योंकिGetStockObject
एक सामान्य वस्तु देता है। - lpszMenuName: उपयोग करने के लिए मेनू बार का संसाधन नाम। यदि कोई मेनू बार आवश्यक नहीं है, तो यह फ़ील्ड NULL हो सकती है।
- lpszClassName: इस विंडो श्रेणी संरचना की पहचान करने वाला वर्ग नाम। इस उदाहरण में,
CLSNAME
वैश्विक चर विंडो वर्ग नाम संग्रहीत करता है। - hIconSm: छोटे वर्ग के आइकन के लिए एक हैंडल।
इस संरचना को प्रारंभ करने के बाद, RegisterClassEx
फ़ंक्शन को कहा जाता है। यह विंडो क्लास को विंडोज़ के साथ पंजीकृत करने का कारण बनता है, जिससे यह एप्लिकेशन को पता चलता है। यह विफलता पर 0 देता है।
अब जब विंडो क्लास पंजीकृत हो गई है, तो हम CreateWindowEx
का उपयोग करके विंडो प्रदर्शित कर सकते हैं। तर्क हैं:
- stylesex: विस्तारित विंडो शैलियाँ। डिफ़ॉल्ट मान WS_EX_LEFT है।
- clsname: वर्ग का नाम
- टोपी: खिड़की का शीर्षक, या शीर्षक। इस मामले में, यह कैप्शन है जो एक विंडो के टाइटल बार में प्रदर्शित होता है।
- शैलियों: खिड़की शैलियों। यदि आप इस तरह की एक शीर्ष-स्तरीय (मूल) विंडो बनाना चाहते हैं, तो पास करने के लिए ध्वज WS_OVERLAPPEDWINDOW है।
- x: विंडो के ऊपरी-बाएँ कोने का x-निर्देशांक।
- y: खिड़की के ऊपरी-बाएँ कोने का y- समन्वय
- cx: विंडो की चौड़ाई
- साइबर: खिड़की की ऊंचाई
- hwndParent: पैरेंट विंडो को हैंडल। चूंकि यह विंडो अपने आप में एक मूल विंडो है, इसलिए यह तर्क NULL है।
- hMenuOrID: यदि विंडो बनाई जा रही है, तो पैरेंट विंडो है, तो यह तर्क विंडो मेनू का एक हैंडल है। इसे क्लास मेनू के साथ भ्रमित न करें, जो
WNDCLASSEX::lpszClassName
। कक्षा मेनू समान श्रेणी नाम वाली खिड़कियों के सभी उदाहरणों के लिए सामान्य है। हालाँकि, यह तर्क इस उदाहरण के लिए विशिष्ट है। यदि बनाई जा रही विंडो एक चाइल्ड विंडो है, तो यह चाइल्ड विंडो की आईडी है। इस मामले में, हम बिना मेनू के साथ एक पैरेंट विंडो बना रहे हैं, इसलिए NULL को पास किया गया है। - hInst: अनुप्रयोग के उदाहरण के लिए हैंडल।
- आदि: अतिरिक्त जानकारी जो विंडो की विंडो प्रक्रिया को पारित की जाती है। यदि कोई अतिरिक्त जानकारी प्रसारित नहीं करनी है, तो NULL को पास करें।
तो x
या y
या cx
या cy
है CW_USEDEFAULT
, तर्क के मूल्य विंडोज द्वारा निर्धारित किया जाएगा तो उस। जो इस उदाहरण में किया गया है।
CreateWindowEx
नए बनाए गए विंडो के हैंडल को लौटाता है। यदि विंडो निर्माण विफल रहा, तो यह NULL
वापस आ गया।
हम तब ShowWindow
को कॉल करके विंडो दिखाते हैं। इस फ़ंक्शन के लिए पहला तर्क विंडो का हैंडल है। दूसरा तर्क शो स्टाइल है, जो इंगित करता है कि विंडो को कैसे प्रदर्शित किया जाए। ज्यादातर आवेदन केवल WinMain
में cmdshow
गए cmdshow
तर्क को पारित करते हैं। खिड़की दिखाया गया है के बाद, यह करने के लिए एक फोन के द्वारा अद्यतन किया जाना चाहिए UpdateWindow
। यह विंडो में अपडेट संदेश भेजने का कारण बनता है। हम सीखेंगे कि दूसरे ट्यूटोरियल में इसका क्या मतलब है।
अब आवेदन का दिल आता है: संदेश पंप। यह ऑपरेटिंग सिस्टम द्वारा इस एप्लिकेशन को भेजे गए संदेशों को पंप करता है और संदेशों को विंडो प्रक्रिया में भेज देता है। GetMessage
कॉल गैर-शून्य देता है जब तक कि एप्लिकेशन एक संदेश प्राप्त नहीं करता है जो इसे छोड़ने का कारण बनता है, जिस स्थिति में यह 0. वापस आता है। एकमात्र तर्क जो हमें चिंतित करता है वह MSG
संरचना का सूचक है जो संदेश के बारे में जानकारी से भरा होगा। अन्य तर्क सभी 0 हैं।
संदेश लूप के अंदर, TranslateMessage
वर्चुअल-कुंजी संदेशों को वर्ण संदेशों में अनुवादित करता है। इसका अर्थ, फिर से, हमारे लिए महत्वहीन है। यह एक MSG
संरचना को MSG
करता है। इसके बाद सीधे कॉल, DispatchMessage
, विंडो की विंडो प्रक्रिया में इसके तर्क द्वारा इंगित किए गए संदेश को भेजती है। WinMain
को आखिरी चीज़ एक स्थिति कोड वापस करना होगा। MSG
संरचना के wParam
सदस्य में यह रिटर्न वैल्यू होती है, इसलिए इसे लौटा दिया जाता है।
लेकिन यह सिर्फ WinMain
फ़ंक्शन के लिए है। अन्य फ़ंक्शन winproc
, विंडो प्रक्रिया है। यह विंडोज़ द्वारा भेजे गए विंडो के संदेशों को संभाल लेगा। winproc
लिए हस्ताक्षर है:
- hwnd: उस विंडो का हैंडल जिसके संदेशों को संसाधित किया जा रहा है।
- wm: विंडो संदेश पहचानकर्ता
- wp: संदेश सूचना तर्क में से एक। यह
wm
तर्क पर निर्भर करता है - lp: संदेश सूचना तर्कों में से एक। यह
wm
तर्क पर निर्भर करता है। यह तर्क आमतौर पर संकेत या हैंडल को प्रसारित करने के लिए उपयोग किया जाता है
इस सरल कार्यक्रम में, हम स्वयं कोई संदेश नहीं संभालते हैं। लेकिन इसका मतलब यह नहीं है कि विंडोज या तो नहीं है। यही कारण है कि एक को DefWindowProc
को कॉल करना होगा, जिसमें डिफ़ॉल्ट विंडो हैंडलिंग कोड होता है। यह फ़ंक्शन प्रत्येक विंडो प्रक्रिया के अंत में कॉल किया जाना चाहिए।
एक हैंडल क्या है?
एक हैंडल एक डेटा प्रकार है जो एक अनोखी वस्तु का प्रतिनिधित्व करता है। वे संकेत हैं, लेकिन ऑपरेटिंग सिस्टम द्वारा बनाए रखा गुप्त डेटा संरचनाओं के लिए। इन संरचनाओं के विवरण से हमें चिंतित होने की आवश्यकता नहीं है। सभी उपयोगकर्ताओं को बस एक एपीआई कॉल का उपयोग करके एक हैंडल बनाना / फिर से बनाना है, और उस प्रकार के हैंडल को ले जाकर अन्य एपीआई कॉल के लिए इसे पास करना होगा। हम इस्तेमाल किया संभाल का एकमात्र प्रकार थाHWND
द्वारा दिया CreateWindowEx
। स्थिरांक
इस उदाहरण में, हम मुट्ठी भर स्थिरांक का सामना करते हैं, जो सभी-कैप में होते हैं और 2 या 3 अक्षर उपसर्ग के साथ शुरू होते हैं। (विंडोज प्रकार भी ऑल-कैप्स में हैं)- IDI_APPLICATION: डिफ़ॉल्ट एप्लिकेशन आइकन वाले संसाधन नाम। इसका उपयोग
LoadIcon
याLoadImage
(इस उदाहरण में LoadIcon) के साथ किया जाता है। - IDC_ARROW: संसाधन नाम डिफ़ॉल्ट एप्लिकेशन कर्सर की गणना करता है। इसका उपयोग
LoadIcon
याLoadImage
(इस उदाहरण में LoadIcon) के साथ किया जाता है। - WHITE_BRUSH: एक स्टॉक ऑब्जेक्ट का नाम। यह स्टॉक ऑब्जेक्ट सफेद ब्रश है।
- MB_ICONERROR: त्रुटि चिह्न प्रदर्शित करने के लिए
MessageBox
साथ उपयोग किया गया एक ध्वज। - WS_EX_LEFT: डिफ़ॉल्ट विस्तारित विंडो शैली। यह विंडो को बाएँ-संरेखित गुण का कारण बनता है।
- WS_OVERLAPPEDWINDOW: एक विंडो शैली जो दर्शाती है कि विंडो को टाइटल बार, साइज़ बॉक्स के साथ पैरेंट विंडो होना चाहिए, और अन्य तत्व टॉप-लेवल विंडो के लिए विशिष्ट हैं।
- CW_USEDEFAULT: के साथ प्रयोग किया जाता है
CreateWindowEx
केx
,y
,cx
, याcy
तर्क। जिस तर्क के लिएCW_USEDEFAULT
पारित किया गया था, उसके लिए एक वैध मान चुनने के लिए विंडोज का कारणCW_USEDEFAULT
।
विंडोज प्रकार
विंडोज के लिए प्रोग्रामिंग करते समय, आपको Win32 प्रकारों के लिए उपयोग करना होगा, जो बिलियन प्रकारों के लिए उपनाम हैं। ये प्रकार सभी कैप्स में हैं। इस कार्यक्रम में उपयोग किए जाने वाले अन्य प्रकार हैं:- TCHAR: सामान्य वर्ण प्रकार। यदि
UNICODE
को परिभाषित किया जाता है, तो यह एकwchar_t
। Otheriwse, यह एक हैchar
। - UINT: एक अहस्ताक्षरित पूर्णांक। विंडो प्रक्रियाओं और अन्य उद्देश्यों में संदेश पहचानकर्ता का प्रतिनिधित्व करने के लिए उपयोग किया जाता है।
- WPARAM: Win16 में, यह एक WORD तर्क था (इसलिए
W
उपसर्ग)। Win32 की शुरुआत के साथ, हालांकि, यह अबUINT_PTR
। यह इन विंडोज उपनामों के बिंदु को दिखाता है; वे कार्यक्रमों को परिवर्तन से बचाने के लिए हैं। - LPARAM: यह एक
LONG
बहस है (Win64 मेंLONG_PTR
)। - PTSTR:
P
अर्थ है सूचक।T
अर्थ है जेनेरिक वर्ण, औरSTR
अर्थ है स्ट्रिंग। इस प्रकार, यहTCHAR
स्ट्रिंग के लिए एक संकेतक है। अन्य स्ट्रिंग प्रकारों में शामिल हैं:- LPTSTR: के रूप में एक ही
PTSTR
- LPCTSTR: का मतलब है
const TCHAR *
- PCTSTR: के रूप में एक ही
LPCTSTR
- LPWSTR: वाइड स्ट्रिंग (
wchar_t *
) - LPCWSTR: कांस्टेबल
const wchar_t *
- PWSTR: के रूप में एक ही
LPWSTR
- और बहुत कुछ जैसा कि आप देख सकते हैं, Win32 प्रकार समझने के लिए एक परेशानी हो सकती है, विशेष रूप से इतने पर्यायवाची प्रकार के साथ, जो Win16 की एक कलाकृति है।
- LPTSTR: के रूप में एक ही
- LRESULT: इस प्रकार का उपयोग विंडो प्रक्रियाओं के रिटर्न वैल्यू को दर्शाने के लिए किया जाता है। यह आमतौर पर एक लंबी (इसलिए
L
) है।