One-day Windows API training (21) setwindowlongptr and getwindowlongptr Functions

Source: Internet
Author: User
In software development, everyone has always been persistent in this issue, which is "reused ". I always want to write the code by myself. It is highly adaptable and can take root wherever it is. Therefore, object-oriented languages emerge one after another, and every one insists that code can be reused the most. In object-oriented systems, C ++ is very powerful. Next we will use C ++ to encapsulate the program described above, so that it can be reused or organized more clearly.
#001
#002 int apientry _ twinmain (hinstance,
#003 hinstance hprevinstance,
#004 lptstr lpcmdline,
#005 int ncmdshow)
#006 {
#007 unreferenced_parameter (hprevinstance );
#008 unreferenced_parameter (lpcmdline );
#009
#010 ccaiwin caiwin;
#011
#012 caiwin. myregisterclass (hinstance );
#013 if (! Caiwin. initinstance (hinstance, ncmdshow ))
#014 {
#015 return 0;
#016}
#017
#018 return caiwin. runmessage ();
#019}

This code is different from the call described earlier.
In row 10th, A ccaiwin object caiwin is created.
Line 3 calls the registration function myregisterclass in the object ccaiwin to register a window.
Row 13th initializes the creation of a window.
Row 3 calls the message processing function runmessage of the caiwin object.

In this way, a basic application framework is developed. Any modification to the content of an object will not affect calls to this function. That is to say, if you do not change those functions, you will never need to modify the content in the winmain function.

Next, let's take a look at how ccaiwin is written. Its Class is defined as follows:
#001 # include <string>
#002
#003 //
#004 // encapsulate a window class.
#005 // Cai junsheng 2007/07/27
#006 //
#007 class ccaiwin
#008 {
#009 public:
#010 ccaiwin (void );
#011 virtual ~ Ccaiwin (void );
#012
#013 atom myregisterclass (hinstance );
#014 bool initinstance (hinstance, int ncmdshow );
#015 int runmessage (void );
#016 hinstance getappinstance (void)
#017 {
#018 return m_hinstance;
#019}
#020 protected:
#021 static lresult callback wndproc (hwnd,
#022 uint message, wparam, lparam );
#023 static int_ptr callback about (hwnd hdlg,
#024 uint message, wparam, lparam );
#025 protected:
#026 hinstance m_hinstance;
#027 hwnd m_hwnd;
#028
#029 STD: wstring m_strwindowclass;
#030 STD: wstring m_strtitle;
#031 };
The class ccaiwin defined in Row 3.
Row 13th declares the registration function of myregisterclass.
Row 14th declares the initinstance initialization window function.
Row 15th declares the runmessage message processing function.
Row 3 defines the getappinstance function to get the application handle.
Row 21st is the message processing function for declaring the window. It is a static member function, so it has a global address. Therefore, it does not have the this pointer and cannot directly access member variables in this class. You need to use other methods to pass it.
Row 23rd is about the message processing function of the dialog box.
Row 3 stores the application handle.
Row 27th is the handle to save the main window.
Row 29th is the name of the Save registration window.
Row 30th is the title displayed in the SAVE window.

Next we will carefully check the class implementation file.
#001 //
#002 // function: initinstance (hinstance, INT)
#003 //
#004 // purpose: Save the program instance handle and display it in the create window.
#005 //
#006 // Cai junsheng 2007/07/27 QQ: 9073204
#007 //
#008 bool ccaiwin: initinstance (hinstance, int ncmdshow)
#009 {
#010 //
#011 m_hinstance = hinstance;
#012
#013 m_hwnd = createwindow (m_strwindowclass.c_str (), m_strtitle.c_str (),
#014 ws_overlappedwindow,
#015 cw_usedefault, 0, cw_usedefault, 0, null, null, hinstance, null );
#016
#017 if (! M_hwnd)
#018 {
#019 return false;
#020}
#021
#022 // Save the class pointer to the gwl_userdata field in the window,
#023 // so that class pointers can be obtained in the message function.
#024 setwindowlongptr (m_hwnd, gwl_userdata, (long) (long_ptr) This );
#025
#026 showwindow (m_hwnd, ncmdshow );
#027 updatewindow (m_hwnd );
#028
#029 return true;
#030}
The window is created here. Unlike the previously created window, there is only one difference, that is, the setwindowlongptr function is called in row 24th to save the object pointer to the custom data of the window, in this way, the following static member function wndproc can be used to compile class members. As follows:
#001 //
#002 // function: wndproc (hwnd, uint, wparam, lparam)
#003 //
#004 // purpose: to process messages in the main window.
#005 //
#006 // Cai junsheng 2007/07/27 QQ: 9073204
#007 //
#008 lresult callback ccaiwin: wndproc (hwnd, uint message,
#009
#010 wparam, lparam)
#011 {
#012 //Obtain the class pointer corresponding to the window.
#013 long_ptr plptrwin = getwindowlongptr (hwnd, gwlp_userdata );
#014 if (plptrwin = NULL)
#015 {
#016 return defwindowproc (hwnd, message, wparam, lparam );
#017}
#018
#019 //
#020 ccaiwin * pwin = reinterpret_cast <ccaiwin *> (plptrwin );
#021
#022 int wmid, wmevent;
#023 paintstruct pS;
#024 HDC;
#025
#026 switch (Message)
#027 {
#028 case wm_command:
#029 wmid = loword (wparam );
#030 wmevent = hiword (wparam );
#031 // menu option command response:
#032 switch (wmid)
#033 {
#034 case idm_about:
#035 dialogbox (pwin-> getappinstance (), makeintresource (idd_aboutbox ),
#036 hwnd, ccaiwin: About );
#037 break;
#038 case idm_exit:
#039 destroywindow (hwnd );
#040 break;
#041 default:
#042 return defwindowproc (hwnd, message, wparam, lparam );
#043}
#044 break;
#045 case wm_paint:
#046 {
#047 HDC = beginpaint (hwnd, & PS );
#048 //
#049 STD: wstring strshow (_ T ("Implementation of the C ++ window class, 2007-07-27 "));
#050 textout (HDC, 10, 10, strshow. c_str (), (INT) strshow. Length ());
#051
#052 //
#053 endpaint (hwnd, & PS );
#054}
#055 break;
#056 case wm_destroy:
#057 // set the window class pointer to null.
#058 setwindowlongptr (hwnd, gwl_userdata, null );
#059
#060 postquitmessage (0 );
#061 break;
#062 default:
#063 return defwindowproc (hwnd, message, wparam, lparam );
#064}
#065 return 0;
#066}
The above 13th rows obtain the Class Object Pointer saved in the window, and then convert the type to the ccaiwin pointer of the window, so that you can use the class member, for example, call pwin-> getappinstance () in row 35th ().

In fact, in the encapsulation of static member functions, there are three methods to pass class pointers, which are the simplest. One is used in MFC, which uses a window and class pointer ing array. One is to use thunk code in wtl to associate a window with a static function. Like the above method, it is used in the Second Life source program of the game. If it is a general application, rather than a large framework, this simple method is the best.

The getwindowlongptr and setwindowlongptr functions are declared as follows:
Winuserapi
Long
Winapi
Getwindowlonga (
_ In hwnd,
_ In int nindex );
Winuserapi
Long
Winapi
Getwindowlongw (
_ In hwnd,
_ In int nindex );
# Ifdef Unicode
# Define getwindowlong getwindowlongw
# Else
# Define getwindowlong getwindowlonga
# Endif //! Unicode

Winuserapi
Long
Winapi
Setwindowlonga (
_ In hwnd,
_ In int nindex,
_ In long dwnewlong );
Winuserapi
Long
Winapi
Setwindowlongw (
_ In hwnd,
_ In int nindex,
_ In long dwnewlong );

# Ifdef Unicode
# Define setwindowlong setwindowlongw
# Else
# Define setwindowlong setwindowlonga
# Endif //! Unicode
# Define getwindowlongptra getwindowlonga
# Define getwindowlongptrw getwindowlongw
# Ifdef Unicode
# Define getwindowlongptr getwindowlongptrw
# Else
# Define getwindowlongptr getwindowlongptra
# Endif //! Unicode

# Define setwindowlongptra setwindowlonga
# Define setwindowlongptrw setwindowlongw
# Ifdef Unicode
# Define setwindowlongptr setwindowlongptrw
# Else
# Define setwindowlongptr setwindowlongptra
# Endif //! Unicode

HwndIs the window handle.
NindexIs the index value for accessing window object data. For example, gwlp_userdata and gwlp_wndproc.
DwnewlongIs the new value.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.