LRESULT and extern variable

Sep 6, 2015 at 8:03am
Can you explain me what means LRESULT?
1
2
3
4
5
6
7
8
9
10
typedef struct COORDS_STRUCT {
    int x;
    int y;
} COORDS;

COORDS coords;

...

coords = SendMessage(dialog, MAP_RotateCoords, x, y);


error C2679: binary '=' : no operator found which takes a right-hand operand of type 'LRESULT' (or there is no acceptable conversion)
map_viewer.h(69): could be 'COORDS_STRUCT &COORDS_STRUCT::operator =(const COORDS_STRUCT &)'
1> while trying to match the argument list '(COORDS, LRESULT)'

Can SendMessag return struct or the LRESULT must be always a pointer?
Last edited on Sep 7, 2015 at 1:37pm
Sep 6, 2015 at 9:38am
what means LRESULT
The type returned by SendMessage
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644950%28v=vs.85%29.aspx
It is either long long or long depending on if your app is 64/32 bit.

Can SendMessag return struct
WinAPI is a C aAPI and there is no overloading in C, so there is only one functon with only one return type.
Sep 6, 2015 at 11:35am
Thank you. My problem is that I do not understand how declare the things so that I could return LRESULT from function.

I have

Shared struct:

1
2
3
4
typedef struct COORDS_STRUCT {
	int x;
	int y;
} COORDS, *PCOORDS;

mapview.cpp:

1
2
3
4
5
6
7
8
9
10
COORDS coords; // struct to save calculated coords

I need do create function which returns LRESULT to send the pointer to the struct

PCOORDS RotateCoords(HWND window, int x, int y)
{
 // calculate coords here and return LRESULT pointing to coords
  return coords;  
}


So when i will call
 
pcoords = SendMessage(dialog, MAP_RotateCoords, x, y);

The result from the function would get to pcoords.

I know there are lots of errors, but how to solve it completely?
Sep 6, 2015 at 11:44am
SendMessage returns whatever message handler returns (and it must be LPARAM), so you can fit any singned integral 32/64bit value or a pointer (as you can cast pointers to integer of sufficient size and back). So you can return a pointer cast to LPARAM and cast it back at receiver.

If you only want to target 64bit, then you can squeese 2 4bytes ints to one 4byte lparam and unpach it later to avoid pointer.
Sep 6, 2015 at 2:29pm
I don't understand you what you speak about LPARAM. LPARAM is expected as argument for SendMessage and not return type. There is example at msdn:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    CHAR szOtherThing[512];

    WCHAR wszDomain[256];

    HWND hDomainEdit;

    HWND hOtherEdit;

    HWND hButton;


    #define DOMAIN_EDIT_ID 1019

    #define OTHER_EDIT_ID 1020

    #define OK_BUTTON_ID 1021


    BOOL DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {

        if (msg == WM_INIT) {

            InitComCtl32();

            hDomainEdit = GetDlgItem(hDlg, DOMAIN_EDIT_ID);

            hOtherEdit = GetDlgItem(hDlg, OTHER_EDIT_ID);

            hButton = GetDlgItem(hDlg, OK_BUTTON_ID);

            /*...*/

            return FALSE;

        } else if (msg == WM_COMMAND) {

            WORD wNotifyCode = HIWORD(wParam);

            WORD wId = LOWORD(wParam);

            if (wId == OK_BUTTON_ID && wNotifyCode == BN_CLICKED) {

                int length = (int) SendMessageA(hOtherEdit, WM_GETTEXT, (WPARAM) 512, (LPARAM) szOtherThing);

                /* length is non-zero in WinXP and Win7 */

                length = (int) SendMessageW(hDomainEdit, WM_GETTEXT, (WPARAM) 256, (LPARAM) wszDomain);

                /* length is non-zero in WinXP, zero in Win7!  Same input!  Error find?  Medal get? */

                /* ... think about doing other stuff, but can't without a domain name ... */

            }

        } // don't process other messages, just out of spite.  just kidding, it's for brevity

    }


And he does not use LPARAM anywhere at the output. You probably mean input (the 3rd argument) of SendMessage
Sep 6, 2015 at 2:55pm
I meant LRESULT. Copied from wrong place.

In your case, DialogProc is message hanler and its return type will be converted to LRESULT and sent to whoever sent message.
Sep 6, 2015 at 7:07pm
Almost there.

But why this happens.

In shared header:
1
2
3
4
5
typedef struct COORDS_STRUCT {
	int x;
	int y;
} COORDS, *PCOORDS;
PCOORDS pcoords;


pcoords will be used in multiple files to get LRESULT from SendMessage.

in cpp file where I define the function I have:
1
2
COORDS coords;
pcoords = &coords; // used to return coords from SendMessage call to mapview.cpp 


error missing declaration for pcoords (but the file with shared data was already included).... But

1
2
COORDS coords;
PCOORDS pcoords = &coords; // used to return coords from SendMessage call to mapview.cpp 

gives error C2086: 'PCOORDS pcoords' : redefinition ...
Sep 6, 2015 at 7:12pm
In shared header:

PCOORDS pcoords;
Already miltiple definitions of variable. Will lead to linking errors

If you really need shared global variable, do not define it:
Header
extern PCOORDS pcoords;

Cpp (a single cpp)
PCOORDS pcoords /*= stuff*/;
Sep 6, 2015 at 7:55pm
What I mean by "Shared" is that I include the header file on multiple places.
pcoords is local variable, not global.

Yes, I have problem with multiple re/definitions. Should I remove it from the "shared" file and declare PCOORDS pcoords; separately in every file? (cca 10 files)
Last edited on Sep 6, 2015 at 7:55pm
Sep 6, 2015 at 8:23pm
What I mean by "Shared" is that I include the header file on multiple places.
If you are including header in multiple places, then you should not have variables at global scope: those will be duplicated in each translation unit

pcoords is local variable, not global.
If it is not inside function, class definition, it is global. With external linkage.

Should I remove it from the "shared" file and declare PCOORDS pcoords; separately in every file?
That depends on what you need. If you want each compiltion using to have own pcoords with no relation to each other (changes in one CU will not be seen in another), make it a variable with internal linkage: either declare it as static, or place it in unnamed namespace.
If you need it to be global access point to single object, declare it in headers (extern) and define in single CU.
Sep 7, 2015 at 10:34am
What is CU?
Sep 7, 2015 at 10:35am
Compilation Unit
Sep 7, 2015 at 12:08pm
Now I have in shared header:

1
2
3
4
extern struct COORDS_STRUCT {
	int x;
	int y;
} COORDS, *PCOORDS;


and in cpp which includes the shared file I have:
1
2
extern struct COORDS coords;
extern struct PCOORDS pcoords = &coords;


This tells me error C2514: 'PCOORDS' : class has no constructors... I would like to point to the coords variable.
Sep 7, 2015 at 12:23pm
1
2
3
4
extern struct COORDS_STRUCT {
	int x;
	int y;
} COORDS, *PCOORDS;
DEclares variables COORDS and PCOORDS, not types.

Why did you touch your struct at all. I clearly stated what you need to add.

Sep 7, 2015 at 12:48pm
OK, once again. I try declare them as globals. First I declare the struct in shared header:

1
2
3
4
typedef struct COORDS_STRUCT {
	int x;
	int y;
} COORDS, *PCOORDS;


and then in header for module:
1
2
extern struct COORDS coords;
extern struct PCOORDS pcoords;

And this tells me error redefinition; different basic types
see declaration of 'COORDS'
Sep 7, 2015 at 12:58pm
COORDS is not a struct. It is typedef for struct COORDS_STRUCT.

Here is the working example:
Header: http://coliru.stacked-crooked.com/a/bac9303321a97beb
Cpp: http://coliru.stacked-crooked.com/a/04d9175e757445eb
Main: http://coliru.stacked-crooked.com/a/aa53f5ff09a0a14b
Last edited on Sep 7, 2015 at 1:06pm
Sep 7, 2015 at 1:36pm
Thank you very much. Now it successfully compiled.
Topic archived. No new replies allowed.