Reputation: 455
This code displays a window with a text label saying: "Please Enter A Number", and a button.
When you click the button it should replace the text with " TEXT ". It works, but it writes/prints the new text on top of the first text. So its overlapping.
I want the string of text to change instead of writing over the first one, but I don't know how as I'm new to windows application development.
Please help me out guys.
The whole source is:
#include <windows.h>
#include <iostream>
using namespace std;
enum { ID_LABEL = 1,ID_BUTTON0};
static HWND static_label, button0;
HDC hdc;
HBRUSH NewBrush;
HINSTANCE g_hInst;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
LPCTSTR className = TEXT("myClass");
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbWndExtra = 0;
wc.cbClsExtra = 0;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("myClass");
wc.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(48, 38, 88)));
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, TEXT("ERROR! FAILED TO REGISTER CLASS!"), TEXT("FATAL ERROR!"), MB_IConerror | MB_OK);
return 1;
}
HWND hwnd = CreateWindowEx(0, TEXT("myClass"), TEXT("WINDOW TITLE"), WS_OVERLAPPEDWINDOW, 450, 100, 500 + 7, 500 + 33 , NULL, NULL, hInstance, NULL);
if(!hwnd)
{
MessageBox(NULL, TEXT("ERROR! FAILED TO CREATE WINDOW!"), TEXT("FATAL ERROR!"), MB_IConerror | MB_OK);
return true;
}
ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_PAINT:
{
}
case WM_CTLCOLORSTATIC:
{
SetBkMode((HDC) wParam, TRANSPARENT);
return (LONG) GetStockObject(NULL_BRUSH);
}
break;
case WM_CREATE:
{
static_label = CreateWindow(L"Static",L"Please Enter A Number",WS_CHILD | WS_VISIBLE,35,15,175,25,hwnd,0, g_hInst,0);
button0 = CreateWindow(L"Button",L"OK",BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,80,220,35,35,hwnd,(HMENU)ID_BUTTON0,g_hInst,0);
}
break;
case WM_COMMAND: //Command from Child windows and menus are under this message
switch(wParam) //the ID is wParam
{
case ID_BUTTON0: //check for our button ID
{
SetWindowText(static_label,L"TEXT");
break;
}
}//switch.
break;
case WM_DESTROY:
PostQuitMessage(0);
break; // pass to DefWindowProc(...) as well
case WM_CLOSE:
DestroyWindow(hwnd);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Upvotes: 1
Views: 11039
Reputation: 1304
Use this code to update the label after the function SetWindowText:
SetWindowText(static_label,L"TEXT");
ShowWindow(static_label, SW_HIDE);
ShowWindow(static_label, SW_SHOW);
Upvotes: 4
Reputation:
RedrawWindow(H_frame,NULL,NULL,RDW_INVALIDATE) worked for me when wanting to provoke WM_CTLCOLORSTATIC-induced changes to take immediate visible effect.
I had earlier got a partial result by SendMessage(H_frame,WM_CTLCOLORSTATIC,0,(int)SpecificControlHandle), but that only worked even in part because a called function was doing GetWindowDC and drawing stuff....
The RedrawWindow(H_frame,NULL,NULL,RDW_INVALIDATE) method is much better. I'd been changing text and background colours for text (and also the control's ID using SetWindowLong(SpecificControlHandle,GWL_ID,SomeNewID) to tell the program which route to take after WM_CTLCOLORSTATIC got sent. Making it get sent was the bit that was solved by RedrawWindow(H_frame,NULL,NULL,RDW_INVALIDATE), hence my post. If it works after changing the STATIC's ID, it ought to work after changing any other attribute or style, etc.
Upvotes: 3
Reputation: 47962
The problem is here:
case WM_CTLCOLORSTATIC:
{
SetBkMode((HDC) wParam, TRANSPARENT);
return (LONG) GetStockObject(NULL_BRUSH);
}
This code tells the static control to draw the text without a background color and not to repaint the background. So the new text is drawn on top of the old text instead of on a fresh background.
If you need some custom background to show through, then you'll have to invalidate that part of the underlying parent window and possibly use something like WS_EX_TRANSPARENT
to ensure the child static control is drawn last. That way, by the time it tries to draw the new text, a fresh background should be painted.
Note that this means you cannot use WS_CLIPCHILDREN
on the underlying parent window, which can increase flicker when things redraw.
Upvotes: 6
Reputation: 308206
Your text is being displayed in a "Static" window, and they don't expect the text to change so they don't handle it gracefully. You need to force the control to erase and redraw itself.
RedrawWindow(static_label, NULL, NULL, RDW_ERASE);
Upvotes: 3