GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Permalink
Join GitHub todaySign up
Find file Copy path
Cannot retrieve contributors at this time
I know I'm being lazy here and I should trawl the header files for myself, but what are the actual types for LPARAM and WPARAM parameters? Are they pointers, or four byte ints? I'm doing some C# interop code and want to be sure I get it working on x64 systems.
Mark Heath
37.1k2525 gold badges111111 silver badges177177 bronze badges
5 AnswersLPARAM is a typedef for LONG_PTR which is a long (signed 32-bit) on win32 and __int64 (signed 64-bit) on x86_64.
WPARAM is a typedef for UINT_PTR which is an unsigned int (unsigned 32-bit) on win32 and unsigned __int64 (unsigned 64-bit) on x86_64. Pes 6 tidak ada musiknya.
537k8282 gold badges564564 silver badges615615 bronze badges
These typedefs go back to the 16-bit days. Originally,
LPARAM was a long (signed 32-bit) and WPARAM was a WORD (unsigned 16-bit), hence the W and L. Due to the common practice of passing casted pointers as message parameters, WPARAM was expanded to 32 bits on Win32, and both LPARAM and WPARAM were expanded to 64 bits on Win64.
In C#, you should use
IntPtr for LPARAM and UIntPtr for WPARAM.
Note that despite the dan04dan04
LP prefix, LPARAM is not a far pointer to an ARAM .
65.1k1717 gold badges139139 silver badges176176 bronze badges
LPARAM refers to a LONG_PTR and WPARAM refers to a UINT_PTR
On x86 they will be 4 bytes and on x64 they will be 8 bytes.
Brian R. BondyBrian R. Bondy
260k102102 gold badges548548 silver badges595595 bronze badges
jpalecekjpalecek
41.3k66 gold badges8484 silver badges127127 bronze badges
What you need my friend is http://www.pinvoke.net/
SerialSebSerialSeb
Not the answer you're looking for? Browse other questions tagged c#c++windows or ask your own question.-->
This note describes the MFC message map facility.
The Problem
Microsoft Windows implements virtual functions in window classes that use its messaging facility. Due to the large number of messages involved, providing a separate virtual function for each Windows message would create a prohibitively large vtable.
Because the number of system-defined Windows messages changes over time, and because applications can define their own Windows messages, message maps provide a level of indirection that prevents interface changes from breaking existing code.
Overview
MFC provides an alternative to the switch statement that was used in traditional Windows-based programs to handle messages sent to a window. A mapping from messages to methods can be defined so that when a message is received by a window, the appropriate method is called automatically. This message-map facility is designed to resemble virtual functions but has additional benefits not possible with C++ virtual functions.
Defining a Message Map
The DECLARE_MESSAGE_MAP macro declares three members for a class.
This macro should be put in the declaration of any class using message maps. By convention, it is at the end of the class declaration. For example:
This is the format generated by AppWizard and ClassWizard when they create new classes. The //{{ and //}} brackets are needed for ClassWizard.
The message map's table is defined by using a set of macros that expand to message map entries. A table starts with a BEGIN_MESSAGE_MAP macro call, which defines the class that is handled by this message map and the parent class to which unhandled messages are passed. The table ends with the END_MESSAGE_MAP macro call.
Between these two macro calls is an entry for each message to be handled by this message map. Every standard Windows message has a macro of the form ON_WM_MESSAGE_NAME that generates an entry for that message.
A standard function signature has been defined for unpacking the parameters of each Windows message and providing type safety. These signatures may be found in the file Afxwin.h in the declaration of CWnd. Each one is marked with the keyword afx_msg for easy identification.
Note
ClassWizard requires that you use the afx_msg keyword in your message map handler declarations.
These function signatures were derived by using a simple convention. The name of the function always starts with
'On '. This is followed by the name of the Windows message with the 'WM_' removed and the first letter of each word capitalized. The ordering of the parameters is wParam followed by LOWORD (lParam) then HIWORD (lParam). Unused parameters are not passed. Any handles that are wrapped by MFC classes are converted to pointers to the appropriate MFC objects. The following example shows how to handle the WM_PAINT message and cause the CMyWnd::OnPaint function to be called:
The message map table must be defined outside the scope of any function or class definition. It should not be put in an extern 'C' block.
Note
ClassWizard will modify the message map entries that occur between the //{{ and //}} comment bracket.
User Defined Windows Messages
User-defined messages may be included in a message map by using the ON_MESSAGE macro. This macro accepts a message number and a method of the form:
In this example, we establish a handler for a custom message that has a Windows message ID derived from the standard WM_USER base for user-defined messages. The following example shows how to call this handler:
The range of user-defined messages that use this approach must be in the range WM_USER to 0x7fff.
Note
ClassWizard does not support entering ON_MESSAGE handler routines from the ClassWizard user interface. You must manually enter them from the Visual C++ editor. ClassWizard will parse these entries and let you browse them just like any other message-map entries.
Registered Windows Messages
The RegisterWindowMessage function is used to define a new window message that is guaranteed to be unique throughout the system. The macro ON_REGISTERED_MESSAGE is used to handle these messages. This macro accepts a name of a UINT NEAR variable that contains the registered windows message ID. For example
The registered Windows message ID variable (WM_FIND in this example) must be a NEAR variable because of the way ON_REGISTERED_MESSAGE is implemented.
Dell xps turn off touchpad. The range of user-defined messages that use this approach will be in the range 0xC000 to 0xFFFF.
Note
ClassWizard does not support entering ON_REGISTERED_MESSAGE handler routines from the ClassWizard user interface. You must manually enter them from the text editor. ClassWizard will parse these entries and let you browse them just like any other message-map entries.
Command Messages
Command messages from menus and accelerators are handled in message maps with the ON_COMMAND macro. This macro accepts a command ID and a method. Only the specific WM_COMMAND message that has a wParam equal to the specified command ID is handled by the method specified in the message-map entry. Command handler member functions take no parameters and return void. The macro has the following form:
Command update messages are routed through the same mechanism, but use the ON_UPDATE_COMMAND_UI macro instead. Command update handler member functions take a single parameter, a pointer to a CCmdUI object, and return void. The macro has the form
Advanced users can use the ON_COMMAND_EX macro, which is an extended form of command message handlers. The macro provides a superset of the ON_COMMAND functionality. Extended command-handler member functions take a single parameter, a UINT that contains the command ID, and return a BOOL. The return value should be TRUE to indicate that the command has been handled. Otherwise routing will continue to other command target objects.
Examples of these forms:
Advanced users can handle a range of commands by using a single command handler: ON_COMMAND_RANGE or ON_COMMAND_RANGE_EX. See the product documentation for more information about these macros.
Note
ClassWizard supports creating ON_COMMAND and ON_UPDATE_COMMAND_UI handlers, but it does not support creating ON_COMMAND_EX or ON_COMMAND_RANGE handlers. However, Class Wizard will parse and let you browse all four command handler variants.
Control Notification Messages
Messages that are sent from child controls to a window have an extra bit of information in their message map entry: the control's ID. The message handler specified in a message map entry is called only if the following conditions are true:
Custom control notification messages may use the ON_CONTROL macro to define a message map entry with a custom notification code. This macro has the form
For advanced usage ON_CONTROL_RANGE can be used to handle a specific control notification from a range of controls with the same handler.
Note
ClassWizard does not support creating an ON_CONTROL or ON_CONTROL_RANGE handler in the user interface. You must manually enter them with the text editor. ClassWizard will parse these entries and let you browse them just like any other message map entries.
The Windows Common Controls use the more powerful WM_NOTIFY for complex control notifications. This version of MFC has direct support for this new message by using the ON_NOTIFY and ON_NOTIFY_RANGE macros. See the product documentation for more information about these macros.
See also
Technical Notes by Number
Technical Notes by Category
I'm importing WinApi functions, writing callbacks etc. (example) in C# and always wonder:
What type do I use for LRESULT in C# ?
int or IntPtr ?
Bitterblue
BitterblueBitterblue
5,00488 gold badges5656 silver badges104104 bronze badges
4 Answers
That's Charles Simonyi, the former head of the Application Software group at Microsoft, the group that developed Word and Excel. He's the one that set identifier naming standards. Since nobody knows how to pronounce his last name, they picked the country he was born in and called it Hungarian notation. The Windows group adopted it as well, but picked the 'bad' kind, System Hungarian. Where the first letter(s) of the identifier is chosen to note the type of the variable. As opposed to the 'good' kind, Apps Hungarian, which selects the prefix by the logical type name instead of the physical type name. Simonyi's version.
So it is L as in Long, W as in Word. LPCWSTR is a dozy like that, Long Pointer to Constant Wide String. A clear problem with System Hungarian is that it doesn't work so well anymore when the architecture changes. Originally picked for 16-bit operating systems (L=32-bits, W=16-bits), migrated to 32-bit without changing the name (W=32-bits), we're at 64-bit today (L=W=64-bits).
So ignore these prefixes, they're just an historical accident. Sims 4 cc top. You really must pick IntPtr for the LRESULT type, it certainly can be a 64-bit value on the 64-bit version of Windows. Very hard to diagnose problems occur when you don't, a common question here.
Off topic, the fuzzy image you see in the background of the photograph is an interesting tidbit about Simonyi as well. Microsoft shared its great success with its employees and turned many of them into multi-millionaires. What you see in the background is a shot of the space shuttle docked to the International Space Station. Simonyi is one of the seven 'space tourists' and bought himself a ticket to ISS. The only one to do so twice, set him back $60 million :)
Hans PassantHans Passant
806k112112 gold badges13691369 silver badges21532153 bronze badges
That names came from historical reasons. In the age of WIndows16 bit WPARAM meant Word-Parameter and LPARAM Long-Parameter in an Hungarian Notation sort-of. moving to 32 bit collapsed both to the same size (32bit integers) but left the names unchanged. LRESULT meant long result, and, again name is kept for historical reasons. Another change happen when windows64 bit came out.Please have a look here in MSDN to have a complete list.In details: both LPARAM and LRESULT are a typedef for LONG_PTR, where LONG_PTR is:
WPARAM is a typedef for UINT_PTR, where UINT_PTR is:
You can see basically the types eventually pointing to the same size bits: the only real difference is if you are using windows 32 or 64.In term of usage meaning, they are general pourpose parameters you can use depending on what the window procedure needs to do. Typically, since a couple of number is not enought, poiter to complex data structures are used and their values passed as WPARAM or LPARAM, so you cannot assign any particular meaning unless you focalize a context.
Felice PollanoFelice Pollano
26.8k77 gold badges5151 silver badges102102 bronze badges
LPARAM is a typedef for LONG_PTR which is a long (signed 32-bit) on win32 and __int64 (signed 64-bit) on x86_64.
WPARAM is a typedef for UINT_PTR which is an unsigned int (unsigned 32-bit) on win32 and unsigned __int64 (unsigned 64-bit) on x86_64.
typedef UINT_PTR WPARAM;
typedef LONG_PTR LPARAM;
In c# You can Use IntPtr
Lresult Callback Wndproc
See What are the definitions for LPARAM and WPARAM?
Upgrade Error Wparam 100 Lparam 1002 2
Communityâ¦
vikkyvikky
3,67233 gold badges3232 silver badges6060 bronze badges
That's an example for hungarian notation:
The remainder of the type names / aliases is supposed to hint at their meaning, i.e.
LRESULT containing some kind of result value, LPARAM and WPARAM being used for parameter variables.
The actual meaning of the stakxstakx
wParam and lParam parameters' content depends on the particular message being sent; they are just generic buckets for message parameters. So it's quite likely that you won't be able to circumvent unsafe type casts.
65.5k1616 gold badges139139 silver badges227227 bronze badges
Not the answer you're looking for? Browse other questions tagged c#winapipointersintptr or ask your own question.Comments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |