Rookie
Rookie

Reputation: 3793

What is the purpose of message handler INT_PTR return value?

I was playing with visual studio's windows forms and the example code had this:

INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    /*code cut*/
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;
    break;

While my other handler function looks like this:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    /*code cut*/
    return 0; // no magical casting or anything, just plain int

I have a clue that in WndProc() when i do a return 0; it means the message wont get handled by the default message handler? but if you do return 1; it would handle with default handler?

But what is the point of return (INT_PTR)TRUE; ? and is it safe to use plain return 0; style there? i tried to compile and it works with just plain integer values too.

Also, im not sure when i should use which of the values, the example code had this:

EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;

But what is the point of the return (INT_PTR)TRUE; there? I changed it to FALSE but couldnt see any difference in functionality.

So, im not sure what this is doing, could anyone clear my mind on this, when should i use return 1 and when should i use return 0, and when should i use something else (if i should) ?

Upvotes: 2

Views: 3096

Answers (2)

meklarian
meklarian

Reputation: 6625

They're somewhat the same. LRESULT is intended to be a return value type that can hold something at least the size of a pointer on a given platform.

From Windows Data Types (Windows)

LRESULT:
Signed result of message processing.
This type is declared in WinDef.h as follows:

typedef LONG_PTR LRESULT;

LONG_PTR:
A signed long type for pointer precision. Use when casting a pointer to a long to perform pointer arithmetic.
This type is declared in <BaseTsd.h> as follows:

#if defined(_WIN64)
 typedef __int64 LONG_PTR; 
#else
 typedef long LONG_PTR;
#endif

The LRESULT type has gone through a number of changes over the years. I believe prior to Win64, it was defined as INT_PTR, but then updated for portability under Win64. A number of other types went through similar changes, such as WPARAM and LPARAM, which used to be 16 bit values in Win16, are 32 bit values in Win32, and are now 64 bit in Win64.

The actual value returned varies depending on the windows message context, as @ildjarn pointed out. There's also a chance the example source that you're reading was probably created before Win64 became a big deal, and may not have been updated or checked for portability since it was written.

For portability, the symbols are defined slightly differently depending on compile target. Hence, (INT_PTR)TRUE is better even if you know the exact value that should be returned that happens to match your build. While return 0; may return the correct result in cases where the return value is empty, this is bad form when compiling under scenarios where portability matters. Using return -1; or even return 0x7FFFFFFF; is even worse, as you may truncate, mask, or otherwise mangle the response that should be given for all platform compile targets.

Using the predefined symbols and constants is best, as the correct values and types will be substituted in for you as you change your compile targets.

Upvotes: 1

ildjarn
ildjarn

Reputation: 62985

The first piece of code is a DialogProc -- quoting the relevant docs:

Return Value
Type: INT_PTR
Typically, the dialog box procedure should return TRUE if it processed the message, and FALSE if it did not. If the dialog box procedure returns FALSE, the dialog manager performs the default dialog operation in response to the message.

The second piece of code is a WindowProc -- quoting the relevant docs:

Return Value
Type: LRESULT
The return value is the result of the message processing and depends on the message sent.

So, that /*code cut*/ part is critically relevant, because which return value you want depends entirely on which message is being handled.

Upvotes: 5

Related Questions