Random Error Messaging from switch statement?

Hello all,

I'm testing getting text from edit controls and what not with win32 (no MFC), and every time I try to write in the 'hEdit' window it throws an exception (the default error message for the 'WM_COMMAND' case ) and I don't know why.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    HWND hEdit = NULL;
    switch(Msg)
    {
	case WM_COMMAND:
		switch(LOWORD(wParam)){
		case IDF_SAVE:
			TCHAR buff[1024];
			GetWindowText(hEdit, buff, 1025); 
			MessageBox(hWnd, buff, " ", MB_OK); 
			break;
		default:
			showErrorMessage(hWnd, "Error"); 
			break;
		}
		break;
	case WM_CREATE:
		hEdit = CreateWindowEx(NULL,"EDIT","", WS_CHILD | WS_VISIBLE | ES_MULTILINE,0,0,800,640,hWnd, (HMENU)IDE_EDIT, NULL, NULL);	
		break;


Since the default isn't even in the 'WM_CREATE' case, I don't see why I would get an exception from a different case. If anyone can help, I would appreciate it as I have been trying to do this for quite some time and it is becoming rather annoying.

Thanks

~ xanimeangiex ~
WM_COMMAND messages are sent to the main Window's WndProc by quite a few interactions with child edit controls, including pressing a keyboard key. That is why as soon as you touch a key you'll get your error message Message Box
If you remove that whole default: case your issue will likely go away.
From MSDN

EN_CHANGE


Sent when the user has taken an action that may have altered text in an edit control. Unlike the EN_UPDATE notification code, this notification code is sent after the system updates the screen. The parent window of the edit control receives this notification code through a WM_COMMAND message.

As freddie1 has already said, you don't need the showErrorMessage(). There are loads of other command messages sent around which aren't error but which are of no interest to you. Just ignore them.

Then, you are passing a length of 1025 to GetWindowText when the buffer is only 1024 long. Not a good idea!

Try

GetWindowText(hEdit, buff, _countof(buff));

(_countof(a) is sizeof(a)/sizeof(a[0]) with some checking...)

Andy
Last edited on
To freddie1, I know that if I remove the default case the error goes away, I just wanted to know why it was happening, thanks for responding I know I did the right thing now :D

To andwestken, I tried that in numerous variations, when I wrote '1024, 1025', I was trying something. Your suggestion also didn't work (sadly :( ) and I don't know why.

Concerning actually getting the text, I've looked into the MSDN documentation, GetWindowText doesn't work, GetDlgItemText (not that function alone, but you know what I mean) doesn't work, WM_TEXT (I haven't tried really but when I did, it didn't work).

I don't know anymore D: Any suggestion would be greatly appreciated.

closed account (DSLq5Di1)
You need to declare hEdit static, else it will be NULL each time the window procedure is called.

static HWND hEdit = NULL;
Rather than argue about it, here is a whole working program for you that consists of a main form with a text box and a button. When you click the button, anything in the text box will be displayed to a MessageBox. There is a Main.cpp and a Form1.h file. Copy both and include them into a new project. I think you'll find the GetWindowText(), GetDlgItem(), etc., work just fine...

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

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

#define IDC_EDIT              2000
#define IDC_BUTTON            2005

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

typedef WndEventArgs*         lpWndEventArgs;

long fnWndProc_OnCreate       (lpWndEventArgs Wea);
long fnWndProc_OnCommand      (lpWndEventArgs Wea);
long fnWndProc_OnDestroy      (lpWndEventArgs Wea);

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

const EVENTHANDLER EventHandler[]=
{
 {WM_CREATE,                  fnWndProc_OnCreate},
 {WM_COMMAND,                  fnWndProc_OnCommand},
 {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
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
//Main.cpp
#include <windows.h>
#include <tchar.h>
#include "Form1.h"


long fnWndProc_OnCreate(lpWndEventArgs Wea)
{
 HWND hCtrl=0;

 Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;
 hCtrl=CreateWindowEx(WS_EX_CLIENTEDGE,_T("edit"),_T(""),WS_CHILD|WS_VISIBLE,25,35,255,25,Wea->hWnd,(HMENU)IDC_EDIT,Wea->hIns,0);
 hCtrl=CreateWindowEx(0,_T("button"),_T("Press To Extract Text"),WS_CHILD|WS_VISIBLE,55,85,200,25,Wea->hWnd,(HMENU)IDC_BUTTON,Wea->hIns,0);
 return 0;
}


long fnWndProc_OnCommand(lpWndEventArgs Wea)
{
 switch(LOWORD(Wea->wParam))
 {
   case IDC_BUTTON:
     {
        if(HIWORD(Wea->wParam)==BN_CLICKED)
        {
           TCHAR szBuffer[256];
           GetWindowText(GetDlgItem(Wea->hWnd,IDC_EDIT),szBuffer,255);
           MessageBox(Wea->hWnd,szBuffer,_T("Clicked Button!"),MB_OK);
        }
     }
     break;
 }

 return 0;
}


long fnWndProc_OnDestroy(lpWndEventArgs Wea)
{
 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("Form1");
 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=0;
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,75,75,320,200,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}





To freddie1, I know that if I remove the default case the error goes away, I just wanted to know why it was happening, thanks for responding


Because, WM_COMMAND messages are sent to a Window Procedure by all the various simple controls such as buttons, edit boxes, etc. Not only that, each control sends many different NOTIFICATION messages, each of which is packaged with a WM_COMMAND message. I believe that is the major topic you haven't grasped yet, that of NOTIFICATION messages.

So, here is a blow by blow description of exactly what is happening in your program. I'm assumming you have an edit control and a button on your main dialog. If so, the split second you set focus or type a character into the edit control, a WM_COMMAND message is sent to your WndProc. The LOWORD(wParam) will likely be the control id of your edit control, which I'm further assumming isn't IDF_SAVE. Since its not, and there are no other cases to test, program execution falls into your default case, and you get that executed even though you don't want it. Like the old saying goes, "computers don't do what you want, they do what you tell them".

@freddie1
- The window only has a giant edit box in it. Nothing else; no button.

I'm further assumming isn't IDF_SAVE. Since its not, and there are no other cases to test, program execution falls into your default case, and you get that executed even though you don't want it. Like the old saying goes, "computers don't do what you want, they do what you tell them"


I figured that was the case, but I wasn't sure since I taught myself all this stuff and have yet to have ANY second verification on how things worked aside from my own speculation.

Thanks for the response

I'm not trying to retrieve the text from a button, I'm trying to do it from a Menu, ('File' menu to be precise).

1
2
        GetWindowText(GetDlgItem(Wea->hWnd,IDC_EDIT),szBuffer,255);
           MessageBox(Wea->hWnd,szBuffer,_T("Clicked Button!"),MB_OK);


^^^ this does not work, it should, but it doesn't. As I stated before, I've tried it and I may be doing something wrong; I don't know. I'm using VS 2010, so it may be bugged since it's been giving me issues lately.

If anyone has any other suggestions, that'd be helpful.

Thanks in advance.
I solved the problem (with getting text from the Edit Control). Apparently, I wasn't doing anything wrong there is a bug with " GetDlgItem " in VS 2010

*It's in this link for future reference
> http://support.microsoft.com/kb/149982 <

Meaning that I can't use any extended window styles. I had to use 'CreateWindow()' instead of 'CreateWindowEx()'; thanks to all who posted, maybe this can help someone in the future.

~ xanimeangiex ~
Topic archived. No new replies allowed.