How can the memory allocation affect the windowcreate function?

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Main.cpp
#include <windows.h>
#include <tchar.h>
#include "Main.h"


long fnWndProc_OnCreate(WndEventArgs& Wea)
{
 data *pd;
 for(int i=0; i < 20; i++){pd->address[i] = i;}
 HWND hCtl;
 int fail;

 Wea.hIns=((LPCREATESTRUCT)Wea.lParam)->hInstance;
 hCtl=CreateWindowEx(0,_T("button"),_T("Button #1"),WS_CHILD | WS_VISIBLE,75,60,150,30,Wea.hWnd,(HMENU)IDC_BUTTON1,Wea.hIns,0);
 hCtl=CreateWindowEx(WS_EX_CLIENTEDGE,_T("edit"),_T(""),WS_CHILD | WS_VISIBLE,75,110,150,30,Wea.hWnd,(HMENU)IDC_EDITBOX1,Wea.hIns,0);
 pd=(data*)LocalAlloc(GPTR,sizeof(pd));
 //pd=(data*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(pd));

 if(pd)
 {
    fail = SetWindowLongPtr(Wea.hWnd,0,(LONG)pd);
    if (fail == 0){CloseWindow(Wea.hWnd);}
 }
 return 0;
}


long fnWndProc_OnCommand(WndEventArgs& Wea)
{
 data* pd;
 HWND hEdit;


 switch(LOWORD(Wea.wParam))
 {
    case IDC_BUTTON1:
         hEdit=GetDlgItem(Wea.hWnd,IDC_EDITBOX1);
         pd=(data*)GetWindowLongPtr(Wea.hWnd,0);
         if(pd->pBuffer)
         {
            GetWindowText(hEdit,pd->pBuffer,255);
            InvalidateRect(Wea.hWnd,NULL,TRUE);
         }
         break;
 }

 return 0;
}

long fnWndProc_OnPaint(WndEventArgs& Wea)
{
 HDC hDC=NULL;
 PAINTSTRUCT ps;
 data* pd;
 int iPrev=0;

 hDC=BeginPaint(Wea.hWnd,&ps);
 iPrev=SetBkMode(hDC,TRANSPARENT);
 pd=(data*)GetWindowLongPtr(Wea.hWnd,0);
 TextOut(hDC,75,160,pd->pBuffer,_tcslen(pd->pBuffer));
 SetBkMode(hDC,iPrev);
 EndPaint(Wea.hWnd,&ps);

 return 0;
}



long fnWndProc_OnDestroy(WndEventArgs& Wea)
{
 data* pd;

 pd=(data*)GetWindowLongPtr(Wea.hWnd,0);
 if(pd->pBuffer)
    HeapFree(GetProcessHeap(),0,pd->pBuffer);
 PostQuitMessage(0);

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("TextOut");
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=sizeof(void*);
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,75,75,320,305,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}

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
//Main.h
#ifndef Main_h
#define Main_h

#define  IDC_BUTTON1          1500
#define  IDC_EDITBOX1         1505

#define dim(x) (sizeof(x) / sizeof(x[0]))

struct data
{
    TCHAR* pBuffer;
    int address[20];
    int badress[20];
    int* paddress;
};

struct WndEventArgs
{
 HWND                         hWnd;
 WPARAM                       wParam;
 LPARAM                       lParam;
 HINSTANCE                    hIns;
};

long fnWndProc_OnCreate       (WndEventArgs& Wea);
long fnWndProc_OnCommand      (WndEventArgs& Wea);
long fnWndProc_OnPaint        (WndEventArgs& Wea);
long fnWndProc_OnDestroy      (WndEventArgs& Wea);

struct EVENTHANDLER
{
 unsigned int                 iMsg;
 long                         (*fnPtr)(WndEventArgs&);
};

const EVENTHANDLER EventHandler[]=
{
 {WM_CREATE,                  fnWndProc_OnCreate},
 {WM_COMMAND,                 fnWndProc_OnCommand},
 {WM_PAINT,                   fnWndProc_OnPaint},
 {WM_DESTROY,                 fnWndProc_OnDestroy}
};
#endif 


I am trying to allocate memory to hold a pointer for the programme itself to use between the functions. When i compile the code above, the button, editbox and static text which should be created in WM_CREATE didn't shown up. I think this happen after i make a several changes in pd pointer allocation.

When i use new and heapalloc, the setwindowlongptr function fail(fail == 0, the window will be minimize). But when i tried with global and local alloc, the window stay(i consider the setwindowlongptr successfully return a pointer), but the createwindowex function which create text, editbox and static text seem to be failed.
Please read documentation for SetWindowLongPtr first:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644898(v=vs.85).aspx

This does not do what you think:
1
2
3
4
5
 if(pd)
 {
    fail = SetWindowLongPtr(Wea.hWnd,0,(LONG)pd);
    if (fail == 0){CloseWindow(Wea.hWnd);}
 }


1. Using a LONG as a 3rd argument makes your program does not work if compiled in 64-bit mode, use LONG_PTR instead.
2. Using 0 as second argument means
Sets the return value of a message processed in the dialog box procedure.
, perhaps you want to set GWLP_USERDATA instead ?
3. Use SetLastError to see if the function really failed.

1
2
3
4
5
6
7
8
if(pd)
 {
    SetLastError (0);
    fail = SetWindowLongPtr(Wea.hWnd, GWLP_USERDATA, (LONG_PTR)pd);
    if (fail == 0 && GetLastError() != 0){  // function failure
        CloseWindow(Wea.hWnd);
   }
 }
Last edited on
1
2
3
4
5
6
SetLastError(0);
 hCtl=CreateWindowEx(0,_T("button"),_T("Button #1"),WS_CHILD | WS_VISIBLE,75,60,150,30,Wea.hWnd,(HMENU)IDC_BUTTON1,Wea.hIns,0);
hCtl=CreateWindowEx(WS_EX_CLIENTEDGE,_T("edit"),_T(""),WS_CHILD | WS_VISIBLE,75,110,150,30,Wea.hWnd,(HMENU)IDC_EDITBOX1,Wea.hIns,0);
 if (hCtl == NULL && GetLastError() != 0){  // function failure
        CloseWindow(Wea.hWnd);
  }


That work, but now the createwindowex still not functioning. I am not sure if my function failure code is written correctly or not, the hwnd parent window didn't minimize does this mean the createwindowex work fine? But i didn't see anything is created.
Last edited on
1. You are overwriting hCtl handle of first window when you call CreateWindowEx second tme.

2. You are using SetLastError incorrectly, you need to call it immediately before SetWindowLongPtr, not calling anything in between.

3. To see if CreateWindowEx succeeded or not, check it's return value.
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Main.cpp
#include <windows.h>
#include <tchar.h>
#include "Main.h"


long fnWndProc_OnCreate(WndEventArgs& Wea)
{
 TCHAR* pBuffer=NULL;
 HWND hCtl;

 Wea.hIns=((LPCREATESTRUCT)Wea.lParam)->hInstance;
 hCtl=CreateWindowEx(0,_T("button"),_T("Button #1"),WS_CHILD | WS_VISIBLE,75,60,150,30,Wea.hWnd,(HMENU)IDC_BUTTON1,Wea.hIns,0);
 hCtl=CreateWindowEx(WS_EX_CLIENTEDGE,_T("edit"),_T(""),WS_CHILD | WS_VISIBLE,75,110,150,30,Wea.hWnd,(HMENU)IDC_EDITBOX1,Wea.hIns,0);
 pBuffer=(TCHAR*)GlobalAlloc(GPTR,256);
 if(pBuffer)
    SetWindowLongPtr(Wea.hWnd,GWLP_USERDATA,(LONG)pBuffer);

 return 0;
}


long fnWndProc_OnCommand(WndEventArgs& Wea)
{
 TCHAR* pBuffer=NULL;
 HWND hEdit;

 switch(LOWORD(Wea.wParam))
 {
    case IDC_BUTTON1:
         hEdit=GetDlgItem(Wea.hWnd,IDC_EDITBOX1);
         pBuffer=(TCHAR*)GetWindowLongPtr(Wea.hWnd,GWLP_USERDATA);
         if(pBuffer)
         {
            GetWindowText(hEdit,pBuffer,255);
            InvalidateRect(Wea.hWnd,NULL,TRUE);
         }
         break;
 }

 return 0;
}


long fnWndProc_OnPaint(WndEventArgs& Wea)
{
 HDC hDC=NULL;
 PAINTSTRUCT ps;
 TCHAR* pBuffer=NULL;
 int iPrev=0;

 hDC=BeginPaint(Wea.hWnd,&ps);
 iPrev=SetBkMode(hDC,TRANSPARENT);
 pBuffer=(TCHAR*)GetWindowLong(Wea.hWnd,GWLP_USERDATA);
 TextOut(hDC,75,160,pBuffer,_tcslen(pBuffer));
 SetBkMode(hDC,iPrev);
 EndPaint(Wea.hWnd,&ps);

 return 0;
}


long fnWndProc_OnDestroy(WndEventArgs& Wea)
{
 TCHAR* pBuffer=NULL;

 pBuffer=(TCHAR*)GetWindowLongPtr(Wea.hWnd,GWLP_USERDATA);
 if(pBuffer)
    GlobalFree(pBuffer);
 PostQuitMessage(0);

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("TextOut");
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=sizeof(void*);
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,75,75,320,305,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}

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
//Main.h
#ifndef Main_h
#define Main_h

#define  IDC_BUTTON1          1500
#define  IDC_EDITBOX1         1505

#define dim(x) (sizeof(x) / sizeof(x[0]))

struct WndEventArgs
{
 HWND                         hWnd;
 WPARAM                       wParam;
 LPARAM                       lParam;
 HINSTANCE                    hIns;
};

long fnWndProc_OnCreate       (WndEventArgs& Wea);
long fnWndProc_OnCommand      (WndEventArgs& Wea);
long fnWndProc_OnPaint        (WndEventArgs& Wea);
long fnWndProc_OnDestroy      (WndEventArgs& Wea);

struct EVENTHANDLER
{
 unsigned int                 iMsg;
 long                         (*fnPtr)(WndEventArgs&);
};

const EVENTHANDLER EventHandler[]=
{
 {WM_CREATE,                  fnWndProc_OnCreate},
 {WM_COMMAND,                 fnWndProc_OnCommand},
 {WM_PAINT,                   fnWndProc_OnPaint},
 {WM_DESTROY,                 fnWndProc_OnDestroy}
};
#endif 


This code was originally from a previous post, by freddie, there is only 1 hCtl to create 2 child window of hWnd. I just a bit confused what did i messed up till both of them goes wrong
trerte
what does that mean?
When i start over to write the code, i found that the culprit is:
for(int i = 0; i <20; i++){dataptr->address[i] = i; };

how does this line link to the l??

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Main.cpp
#include <windows.h>
#include <tchar.h>
#include "Main.h"


long fnWndProc_OnCreate(WndEventArgs& Wea)
{
 DATA* dataptr;
 HWND hCtl;
 for(int i = 0; i <20; i++){dataptr->address[i] = i; };

 Wea.hIns=((LPCREATESTRUCT)Wea.lParam)->hInstance;
 hCtl=CreateWindowEx(0,_T("button"),_T("Button #1"),WS_CHILD | WS_VISIBLE,75,60,150,30,Wea.hWnd,(HMENU)IDC_BUTTON1,Wea.hIns,0);
 hCtl=CreateWindowEx(WS_EX_CLIENTEDGE,_T("edit"),_T(""),WS_CHILD | WS_VISIBLE,75,110,150,30,Wea.hWnd,(HMENU)IDC_EDITBOX1,Wea.hIns,0);

 dataptr=(DATA*)GlobalAlloc(GPTR,sizeof(DATA));

 if(dataptr)
    SetWindowLongPtr(Wea.hWnd,GWLP_USERDATA,(LONG_PTR)dataptr);


 return 0;
}


long fnWndProc_OnCommand(WndEventArgs& Wea)
{
 DATA* dataptr;
 HWND hEdit;

 switch(LOWORD(Wea.wParam))
 {
    case IDC_BUTTON1:
         hEdit=GetDlgItem(Wea.hWnd,IDC_EDITBOX1);

         dataptr=(DATA*)GetWindowLongPtr(Wea.hWnd,GWLP_USERDATA);
         if(dataptr)
         {
            GetWindowText(hEdit,dataptr->pBuffer,255);
            InvalidateRect(Wea.hWnd,NULL,TRUE);
         }
         break;
 }

 return 0;
}


long fnWndProc_OnPaint(WndEventArgs& Wea)
{
 HDC hDC=NULL;
 PAINTSTRUCT ps;
 DATA* dataptr;
 int iPrev=0;

 hDC=BeginPaint(Wea.hWnd,&ps);
 iPrev=SetBkMode(hDC,TRANSPARENT);
 dataptr=(DATA*)GetWindowLongPtr(Wea.hWnd,GWLP_USERDATA);
 TextOut(hDC,75,160,dataptr->pBuffer,_tcslen(dataptr->pBuffer));
 SetBkMode(hDC,iPrev);
 EndPaint(Wea.hWnd,&ps);

 return 0;
}


long fnWndProc_OnDestroy(WndEventArgs& Wea)
{
 DATA* dataptr;

 dataptr=(DATA*)GetWindowLongPtr(Wea.hWnd,GWLP_USERDATA);
 if(dataptr)
    GlobalFree(dataptr);
 PostQuitMessage(0);

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("TextOut");
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=sizeof(void*);
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,75,75,320,305,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}
1
2
3
4
5
6
7
struct data
{
    TCHAR* pBuffer;
    int address[20];
    int badress[20];
    int* paddress;
};


The size of this struct should be 168 bytes on 32 bit compiles, and 174 bytes on 64 bit compiles. Note however, that this ...

1
2
3
4
5
struct data
{
 TCHAR* pBuffer;
 ...
 ...


does not do what you think it is doing. All it does is give you a dangling pointer with no valid memory to which it points. In other words, you've got a pointer to memory, but its pointing at no valid memory. If you want to create a buffer in your struct where you can store textr retrieved with GetWindowText(), you should declare it something like so ...

1
2
3
4
5
6
struct data
{
 TCHAR lpBuffer[256];
 ...
 ...
};
Also, you can't run that for loop which stores values in memory before you've allocated the memory.
I fixed a lot of errors, but this should work ...

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Main.cpp
#include <windows.h>
#include <tchar.h>
#include <cstdio>
#include "Main.h"
FILE* fp=NULL;

long fnWndProc_OnCreate(WndEventArgs& Wea)
{
 data* pd=NULL;
 HWND hCtl;

 fp=fopen("Output.txt","w");
 fprintf(fp,"Entering fnWndProc_OnCreate()\n");
 Wea.hIns=((LPCREATESTRUCT)Wea.lParam)->hInstance;
 hCtl=CreateWindowEx(0,_T("button"),_T("Button #1"),WS_CHILD | WS_VISIBLE,75,60,150,30,Wea.hWnd,(HMENU)IDC_BUTTON1,Wea.hIns,0);
 hCtl=CreateWindowEx(WS_EX_CLIENTEDGE,_T("edit"),_T(""),WS_CHILD | WS_VISIBLE,75,110,150,30,Wea.hWnd,(HMENU)IDC_EDITBOX1,Wea.hIns,0);
 pd=(data*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(data));
 fprintf(fp,"  pd = %d\n\n",(int)pd);
 if(!pd)         // if WM_CREATE fails - just return -1
    return -1;
 SetWindowLongPtr(Wea.hWnd,0,(long)pd);
 for(int i=0; i < 20; i++)
     pd->address[i] = i;
 for(int i=0; i<20; i++)
     fprintf(fp,"  %d\t%d\t%d\n",i,(int)&pd->address[i],(int)pd->address[i]);
 fprintf(fp,"Leaving fnWndProc_OnCreate()\n");

 return 0;
}


long fnWndProc_OnCommand(WndEventArgs& Wea)
{
 data* pd;
 HWND hEdit;

 switch(LOWORD(Wea.wParam))
 {
    case IDC_BUTTON1:
         fprintf(fp,"\nEntering fnWndProc_OnCommand() case IDC_BUTTON1\n");
         hEdit=GetDlgItem(Wea.hWnd,IDC_EDITBOX1);
         pd=(data*)GetWindowLongPtr(Wea.hWnd,0);
         fprintf(fp,"  pd = %d\n",(int)pd);
         if(pd->lpBuffer)
         {
            GetWindowText(hEdit,pd->lpBuffer,255);
            fprintf(fp,"  pd->lpBuffer = %s\n",pd->lpBuffer);
            InvalidateRect(Wea.hWnd,NULL,TRUE);
         }
         fprintf(fp,"Leaving fnWndProc_OnCommand()\n");
         break;
 }

 return 0;
}

long fnWndProc_OnPaint(WndEventArgs& Wea)
{
 HDC hDC=NULL;
 PAINTSTRUCT ps;
 data* pd;
 int iPrev=0;

 hDC=BeginPaint(Wea.hWnd,&ps);
 iPrev=SetBkMode(hDC,TRANSPARENT);
 pd=(data*)GetWindowLongPtr(Wea.hWnd,0);
 TextOut(hDC,75,160,pd->lpBuffer,_tcslen(pd->lpBuffer));
 SetBkMode(hDC,iPrev);
 EndPaint(Wea.hWnd,&ps);

 return 0;
}



long fnWndProc_OnDestroy(WndEventArgs& Wea)
{
 fprintf(fp,"\nEntering fnWndProc_OnDestroy()\n");
 data* pd=NULL;  // Set to NULL, or it will contain gaerbage non-zero number

 pd=(data*)GetWindowLongPtr(Wea.hWnd,0);
 if(pd)
    HeapFree(GetProcessHeap(),0,pd);
 PostQuitMessage(0);
 fprintf(fp,"Leaving fnWndProc_OnDestroy()\n");
 fclose(fp);

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("TextOut");
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=sizeof(void*);
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,75,75,320,305,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}


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
//Main.h
#ifndef Main_h
#define Main_h

#define  IDC_BUTTON1          1500
#define  IDC_EDITBOX1         1505

#define dim(x) (sizeof(x) / sizeof(x[0]))

struct data
{
    TCHAR lpBuffer[256];
    int   address[20];
    int   badress[20];
    int*  paddress;
};

struct WndEventArgs
{
 HWND                         hWnd;
 WPARAM                       wParam;
 LPARAM                       lParam;
 HINSTANCE                    hIns;
};

long fnWndProc_OnCreate       (WndEventArgs& Wea);
long fnWndProc_OnCommand      (WndEventArgs& Wea);
long fnWndProc_OnPaint        (WndEventArgs& Wea);
long fnWndProc_OnDestroy      (WndEventArgs& Wea);

struct EVENTHANDLER
{
 unsigned int                 iMsg;
 long                         (*fnPtr)(WndEventArgs&);
};

const EVENTHANDLER EventHandler[]=
{
 {WM_CREATE,                  fnWndProc_OnCreate},
 {WM_COMMAND,                 fnWndProc_OnCommand},
 {WM_PAINT,                   fnWndProc_OnPaint},
 {WM_DESTROY,                 fnWndProc_OnDestroy}
};
#endif 


Note it opens a debug output.txt file in your working directory where you can easily check the values of lots of things.
Last edited on
If you really want your data::pBuffer to be a simple pointer without any memory associated with it as you originally had it, then you are going to have to not only make a memory allocation for the data object in your WM_CREATE handler, but also another memory allocation for some memory to which data::pBuffer can point. It would be into this latter buffer that GetWindowText() would copy its data from the edit control.

If you are going to do that, using a class rather than a struct might be a better idea (even though in C++ structs can have constructors). In the class constructor you could create the memory buffer for the text, then free it in the destructor. Here would be an example of that ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef CData_h
#define CData_h

class CData
{
 public:
 CData();
 ~CData();

 TCHAR* pBuffer;
 int*   paddress;
 int    address[20];
 int    badress[20];
};
#endif 


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
//Main.h
#ifndef Main_h
#define Main_h

#define  IDC_BUTTON1          1500
#define  IDC_EDITBOX1         1505

#define dim(x) (sizeof(x) / sizeof(x[0]))

struct WndEventArgs
{
 HWND                         hWnd;
 WPARAM                       wParam;
 LPARAM                       lParam;
 HINSTANCE                    hIns;
};

long fnWndProc_OnCreate       (WndEventArgs& Wea);
long fnWndProc_OnCommand      (WndEventArgs& Wea);
long fnWndProc_OnPaint        (WndEventArgs& Wea);
long fnWndProc_OnDestroy      (WndEventArgs& Wea);

struct EVENTHANDLER
{
 unsigned int                 iMsg;
 long                         (*fnPtr)(WndEventArgs&);
};

const EVENTHANDLER EventHandler[]=
{
 {WM_CREATE,                  fnWndProc_OnCreate},
 {WM_COMMAND,                 fnWndProc_OnCommand},
 {WM_PAINT,                   fnWndProc_OnPaint},
 {WM_DESTROY,                 fnWndProc_OnDestroy}
};
#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//CData.cpp
#include "Windows.h"
#include <tchar.h>
#include <cstdio>
#include "CData.h"
extern FILE* fp;

CData::CData()
{
 fprintf(fp,"  Entering CData() Constructor!\n");
 fprintf(fp,"    this          = %d\n",(int)this);
 this->pBuffer=(TCHAR*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,256*sizeof(TCHAR));
 fprintf(fp,"    this->pBuffer = %d\n",(int)this->pBuffer);
 fprintf(fp,"  Leaving CData() Constructor!\n\n");
}

CData::~CData()
{
 fprintf(fp,"  Entering CData() Destructor!\n");
 fprintf(fp,"    this          = %d\n",(int)this);
 BOOL blnFree=HeapFree(GetProcessHeap(),0,this->pBuffer);
 fprintf(fp,"    blnFree       = %d\n",!!blnFree);
 fprintf(fp,"  Leaving CData() Destructor!\n");
}


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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Main.cpp
#include <windows.h>
#include <tchar.h>
#include <cstdio>
#include "Main.h"
#include "CData.h"
FILE* fp = NULL;


long fnWndProc_OnCreate(WndEventArgs& Wea)
{
 CData* pData=NULL;
 HWND hCtl;

 fp=fopen("Output.txt","w");
 fprintf(fp,"Entering fnWndProc_OnCreate()\n");
 Wea.hIns=((LPCREATESTRUCT)Wea.lParam)->hInstance;
 hCtl=CreateWindowEx(0,_T("button"),_T("Button #1"),WS_CHILD | WS_VISIBLE,75,60,150,30,Wea.hWnd,(HMENU)IDC_BUTTON1,Wea.hIns,0);
 hCtl=CreateWindowEx(WS_EX_CLIENTEDGE,_T("edit"),_T(""),WS_CHILD | WS_VISIBLE,75,110,150,30,Wea.hWnd,(HMENU)IDC_EDITBOX1,Wea.hIns,0);
 pData=new CData;
 fprintf(fp,"  pData = %d\n",(int)pData);
 if(!pData)
    return -1;
 SetWindowLongPtr(Wea.hWnd,0,(long)pData);
 for(int i=0; i < 20; i++)
     pData->address[i]=i;
 for(int i=0; i<20; i++)
     fprintf(fp,"  %d\t%d\t%d\n",i,(int)&pData->address[i],pData->address[i]);
 fprintf(fp,"Leaving fnWndProc_OnCreate()\n");

 return 0;
}


long fnWndProc_OnCommand(WndEventArgs& Wea)
{
 CData* pData=NULL;
 HWND hEdit;

 switch(LOWORD(Wea.wParam))
 {
    case IDC_BUTTON1:
         fprintf(fp,"\nEntering fnWndProc_OnCommand() case IDC_BUTTON1\n");
         hEdit=GetDlgItem(Wea.hWnd,IDC_EDITBOX1);
         pData=(CData*)GetWindowLongPtr(Wea.hWnd,0);
         fprintf(fp,"  pData = %d\n",(int)pData);
         GetWindowText(hEdit,pData->pBuffer,255);
         fprintf(fp,"  pData->pBuffer = %s\n",pData->pBuffer);
         InvalidateRect(Wea.hWnd,NULL,TRUE);
         fprintf(fp,"Leaving fnWndProc_OnCommand()\n");
         break;
 }

 return 0;
}

long fnWndProc_OnPaint(WndEventArgs& Wea)
{
 HDC hDC=NULL;
 PAINTSTRUCT ps;
 CData* pData=NULL;
 int iPrev=0;

 hDC=BeginPaint(Wea.hWnd,&ps);
 iPrev=SetBkMode(hDC,TRANSPARENT);
 pData=(CData*)GetWindowLongPtr(Wea.hWnd,0);
 TextOut(hDC,75,160,pData->pBuffer,_tcslen(pData->pBuffer));
 SetBkMode(hDC,iPrev);
 EndPaint(Wea.hWnd,&ps);

 return 0;
}



long fnWndProc_OnDestroy(WndEventArgs& Wea)
{
 fprintf(fp,"\nEntering fnWndProc_OnDestroy()\n");
 CData* pData=NULL;  // Set to NULL, or it will contain gaerbage non-zero number

 pData=(CData*)GetWindowLongPtr(Wea.hWnd,0);
 if(pData)
    delete pData;
 PostQuitMessage(0);
 fprintf(fp,"Leaving fnWndProc_OnDestroy()\n");
 fclose(fp);

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("TextOut");
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=sizeof(void*);
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,75,75,320,305,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}


And here is an output run ...

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
Entering fnWndProc_OnCreate()
  Entering CData() Constructor!
    this          = 3881776
    this->pBuffer = 6441608
  Leaving CData() Constructor!

  pData = 3881776
  0	3881784	0
  1	3881788	1
  2	3881792	2
  3	3881796	3
  4	3881800	4
  5	3881804	5
  6	3881808	6
  7	3881812	7
  8	3881816	8
  9	3881820	9
  10	3881824	10
  11	3881828	11
  12	3881832	12
  13	3881836	13
  14	3881840	14
  15	3881844	15
  16	3881848	16
  17	3881852	17
  18	3881856	18
  19	3881860	19
Leaving fnWndProc_OnCreate()

Entering fnWndProc_OnCommand() case IDC_BUTTON1
  pData = 3881776
  pData->pBuffer = I Like To Play!
Leaving fnWndProc_OnCommand()

Entering fnWndProc_OnDestroy()
  Entering CData() Destructor!
    this          = 3881776
    blnFree       = 1
  Leaving CData() Destructor!
Leaving fnWndProc_OnDestroy()
Last edited on
I get what you mean, thanks. And if i call the SetWindowLongPtr twice with same hwnd argument, the former pointer address will be rewrite right?
It will contain the last value you stored there. Note that, in terms of the WNDCLASSEX::cbWndExtra bytes, you can specify as many bytes as you want in multiples of 4/8. I've personally never required more than about 60 bytes though. Back in Windows 95 times the max was 40 I believe.
Topic archived. No new replies allowed.