Jump to content
  • Advertisement
Sign in to follow this  
SonicD007

Out of scope problem (I think) [C++]

This topic is 2449 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm using C++ and the windows api to make a simple chat program. Right now, I'm still setting up the gui and trying to get some basic things working. I'm having trouble getting the text length from my child windows because I believe they are going out of scope. When I put a breakpoint after the GetWindowTextLength() the handle I pass to that function is always 0x00000000. Here's what the code looks like.


LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
char cChatMessage[256];

HWND hTextBox = NULL;
HWND hSendButton = NULL;
HWND hChatDisplay = NULL;

HDC hdc;
TEXTMETRIC tmFontSize;

RECT rcClientCoor;
GetClientRect(hwnd, &rcClientCoor);
RECT rcTextBoxCoor = { 0, rcClientCoor.bottom - 20, rcClientCoor.right - 200, 20 };
RECT rcSendButtonCoor = { rcTextBoxCoor.right + 20, rcClientCoor.bottom - 20, (rcClientCoor.right - rcTextBoxCoor.right), 20};
RECT rcChatDisplayCoor = { 0, 0, rcTextBoxCoor.right, rcTextBoxCoor.top - 20 };

int iMessageLength;
switch(msg)
{
case WM_CREATE:
hTextBox = CreateWindow(TEXT("Edit"), TEXT(""), WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL,
rcTextBoxCoor.left, rcTextBoxCoor.top, rcTextBoxCoor.right, rcTextBoxCoor.bottom,
hwnd, (HMENU)IDC_TEXTBOX, NULL, NULL);

hSendButton = CreateWindow(TEXT("Button"), TEXT("Send"), WS_VISIBLE | WS_CHILD | WS_BORDER | BS_PUSHBUTTON,
rcSendButtonCoor.left, rcSendButtonCoor.top, rcSendButtonCoor.right, rcSendButtonCoor.bottom,
hwnd, (HMENU)IDC_SEND, NULL, NULL);

hChatDisplay = CreateWindow(TEXT("Edit"), TEXT(""), WS_VISIBLE | WS_CHILD |WS_BORDER | ES_MULTILINE,
rcChatDisplayCoor.left, rcChatDisplayCoor.top, rcChatDisplayCoor.right, rcChatDisplayCoor.bottom,
hwnd, (HMENU)IDC_CHATDISPLAY, NULL, NULL);
break;
case WM_SIZE:

break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_FILE_EXIT:
DestroyWindow(hwnd);
break;
case ID_CONNECT_CONNECTTO:
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_CONNECTTO), hwnd, ConnectToDlgProc);
break;
case ID_HELP_ABOUT:
MessageBox(hwnd, "Created by SonicD007", "About", MB_OK);
break;
case IDC_SEND:
//change from hard coded 256 to get text length somehow
GetDlgItemText(hwnd, IDC_TEXTBOX, (LPSTR)cChatMessage, 256);

SetDlgItemText(hwnd, IDC_TEXTBOX, "");

//This is where the problem is. hTextBox is null (out of scope I believe)
iMessageLength = GetWindowTextLength(hTextBox);

MessageBox(hwnd, (LPCSTR)iMessageLength, "Text length", MB_OK);
InvalidateRect(hwnd, &rcClientCoor, TRUE);
break;
}
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_RETURN:
GetDlgItemText(hwnd, IDC_TEXTBOX, (LPSTR)cChatMessage, 256);

SetDlgItemText(hwnd, IDC_TEXTBOX, "");
InvalidateRect(hwnd, &rcClientCoor, TRUE);
break;
}
break;

case WM_PAINT:
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
GetTextMetrics(hdc, &tmFontSize);
EndPaint(hwnd, &ps);
break;

case WM_CLOSE:
DestroyWindow(hwnd);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Chat Chat v0.1",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
NULL, NULL, hInstance, NULL);

if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}


Any help would be appreciated. Also feel free to critique the code, I know there's no error checking and it looks pretty sloppy at the moment but I appreciate the helpful comments. Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Local variables don't retain their value across different function calls unless they are declared static. However, rather than use static in this case, you should probably use an actual data structure for your window information.

Share this post


Link to post
Share on other sites

Local variables don't retain their value across different function calls unless they are declared static. However, rather than use static in this case, you should probably use an actual data structure for your window information.


Can you show me an example of what you mean with the data structure? Is this a viable approach or is this horribly wrong?

struct myWindow {
TEXT type,
TEXT txt,
DWORD style,
etc...
myWindow(TEXT,TEXT,DWORD, x,y,w,z,HWND,HMENU)
{
CreateWindow()
}
};

Share this post


Link to post
Share on other sites

Can you show me an example of what you mean with the data structure? Is this a viable approach or is this horribly wrong?


There are many approaches, what SiCrane suggest is to collect all the common data into a (global) structure, instead of many individual variables.

Share this post


Link to post
Share on other sites
Sorry but I'm still not getting what I need to do. I tried making the handles global static variables but I'm still getting the handle as unused. Tried making a global struct with three HWND variables declared that were then set to CreateWindow in the WM_CREATE portion and it still wasn't working. I'm obviously doing something wrong =/

Share this post


Link to post
Share on other sites
Can you show us some of the alternatives you tried, and any relevant compile/runtime errors that they produced?

Share this post


Link to post
Share on other sites
Attempt # 1: Tried declaring the variables as static. Result: still null
Attempt # 2: Tried declaring the variables as globals. Result: still null
Attempt # 3: Tried declaring the variables as globals and as static. Result: still null
Attempt # 4: Tried creating a global struct such as: Result: still null

struct myWindow{
HWND window
};

Then when I called CreateWindow() I did it like so:

myWindow mw;
mw.window = CreateWindow(parameters in here);


Everything compiles and runs. I put a breakpoint where I was calling the MessageBox to display the windowtextlength and looked at the line before the MessageBox which was:

iMessageLength = GetWindowTextLength(hTextBox) (mw.window when I tried the struct approach)


Every attempt had hTextBox as unused and iMessageLength was 0 because of that.

Share this post


Link to post
Share on other sites
hTextBox is only set when msg == WM_CREATE so if this never happens hTextBox will always be null.

Share this post


Link to post
Share on other sites
I'm pretty sure the WM_Create message does get sent otherwise I wouldn't be able to see or interact with the child windows

Share this post


Link to post
Share on other sites
Maybe a dumb question, but did you make sure to remove the local versions from WndProc and only update the globals for WM_CREATE? If you put a breakpoint in WM_CREATE and watch your globals/struct, does it get set to a valid-looking value? If so, try setting a data breakpoint on the variable for one of the child HWNDs and see if it gets modified someplace else.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!