Use TextOut() in WM_COMMAND - winapi

I'm trying to print a text in the WM_COMMAND case, because I need a text to be printed after a button was pushed.
Here's the code I have:
switch(msg)
{
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
case WM_COMMAND:
switch (LOWORD(wParam))
{
case 1:
PAINTSTRUCT ps;
HDC hDC;
hDC = BeginPaint(hwnd, &ps);
{
TextOut(hDC, 10, 50, "hello", 5);
}
EndPaint(hwnd, &ps);
UpdateWindow(hwnd);
break;
}
break;
}
Sadly it doesn't print anything.
edit:
I can use TextOut() during WM_COMMAND that way:
HDC hDC;
hDC = GetDC(hwnd);
TextOut(hDC, 10, ypos, "Warnings: ", 10);
UpdateWindow(hwnd);

It's best to structure your program so that all painting is performed in WM_PAINT.
so you could change it to be something like:
LRESULT CALLBACK WndProc(/*blah blah blah*/)
{
static wchar_t my_text[] = L"hello";
static BOOL show_btn_text = FALSE;
HDC dc;
PAINTSTRUCT ps;
switch (msg) {
case WM_COMMAND:
switch (LOWORD(wParam)) {
case 1:
show_btn_text = !show_btn_text;
InvalidateRect(hwnd, NULL, TRUE); //tells windows that the whole client area needs to be repainted
break;
}
return 0;
case WM_PAINT:
dc = BeginPaint(hwnd, &ps);
if (show_btn_text) {
TextOut(dc, 0, 0, my_text, wcslen(my_text));
}
EndPaint(hwnd, &ps);
return 0;
/*the rest of the window procedure
}
}

For painting inside of WM_PAINT: BeginPaint/EndPaint.
For painting outside of WM_PAINT: GetDC/ReleaseDC.

Related

the procedure deal with WM_PAINT didn't draw anything on the window with Direct2D

I am doing a program with Direct2D and I want to paint a flower on the window. However, I could only see a white window with nothing except the menu. I tested, and then I found that the code which deal with the message WM_PAINT didn't work. I added a piece of code that show a message box, but I only heard the sound, and didn't see the box.
The main code:
// other code omitted
ID2D1Factory* pFactory = nullptr;
ID2D1HwndRenderTarget* pRenderTarget = nullptr;
ID2D1SolidColorBrush* pBrush = nullptr;
IWICImagingFactory* pImagingFactory = nullptr;
IWICBitmapDecoder* pBitmapDecoder = nullptr;
IWICFormatConverter* pConverter = nullptr;
ID2D1Bitmap* pBitmap = nullptr;
IWICBitmapFrameDecode* pDecode = nullptr;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// other messages omitted
case WM_CREATE:
{
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory);
pFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(hWnd, D2D1::SizeU(rect.right - rect.left, rect.top - rect.bottom)),
&pRenderTarget);
HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pImagingFactory));
pImagingFactory->CreateDecoderFromFilename(L".\\flower.png", nullptr, GENERIC_READ,
WICDecodeMetadataCacheOnLoad, &pBitmapDecoder);
pBitmapDecoder->GetFrame(0, &pDecode);
pImagingFactory->CreateFormatConverter(&pConverter);
pConverter->Initialize(pDecode, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone,
nullptr, 0.F, WICBitmapPaletteTypeCustom);
pRenderTarget->CreateBitmapFromWicBitmap(pConverter, nullptr, &pBitmap);
}
break;
case WM_PAINT:
{
MessageBox(hWnd, L"WM_PAINT", L"flower", MB_OK | MB_ICONEXCLAMATION); // the test code
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
pRenderTarget->BeginDraw();
pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::Red));
if (pBitmap != nullptr)
pRenderTarget->DrawBitmap(pBitmap, D2D1::RectF(500, 500, 572, 572));
pRenderTarget->EndDraw();
EndPaint(hWnd, &ps);
}
break;
}
}

Why does my button function executes onload of my win32 projcet? C++

I've created a basic GUI using the windows library and I've come across a problem. The GUI builds and performs great but the issue is the button functions execute before the actual window loads. I wanted the button to execute the desired function on press rather than on load. Below is the code where I think the problem lies.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("T3chSpl01ts Version - 1.0");
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc,
5, 5,
greeting, _tcslen(greeting));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
case WM_CREATE:
{
Button = CreateWindow("Button", "Inject",
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 20, 20, 100, 30,
hWnd, (HMENU)ID_INJECT, GetModuleHandle(NULL), NULL);
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case ID_INJECT:
{
::test();
break;
}
}
}
}
return 0;
}
Your WM_CREATE handler is missing a break statement, so code flow "falls through" into your WM_COMMAND handler when the window is created.

Background color of the button is not changed by WM_CTLCOLORBTN

I try to change the default color of the button in my UI.
Here is my CallBacl function
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg)
{
case WM_COMMAND:
switch (wp)
{
case FILE_MENU_NEW:
MessageBeep(MB_ICONINFORMATION);
break;
}
break;
case WM_CREATE:
AddMenus(hWnd);
AddControls(hWnd);
break;
case WM_CTLCOLOREDIT:
{
if (hEdit == (HWND)lp)
{
HDC hdcEdit = (HDC)wp;
SetTextColor(hdcEdit, RGB(255, 255, 255));
SetBkColor(hdcEdit, RGB(48, 56, 66));
return (INT_PTR)hBrush1;
}
}
case WM_CTLCOLORBTN:
{
if (hButton_ok == (HWND)lp)
{
HDC hdcButton_ok = (HDC)wp;
SetTextColor(hdcButton_ok, RGB(255, 255, 255));
SetBkColor(hdcButton_ok, RGB(87, 102, 110));
return (INT_PTR)hBrush;
}
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hWnd, msg, wp, lp);
}
}
Now case WM_CTLCOLOREDIT changes the background color of my text input dialog correctly,
Why is then WM_CTLCOLORBTN fails?

Not get control in this case CDDS_ITEMPREPAINT| CDDS_SUBITEM:

I am using NM_CUSTOMDRAW for changing the color of Tree View item & its child on some conditions.I want to get subitems control individually but dwDrawStage never get this case CDDS_ITEMPREPAINT| CDDS_SUBITEM my code snippet is here:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
int j;
HWND hwndTree;
TVITEM tv;
TVHITTESTINFO hti;
char achBuf[100];
switch (message)
{
case WM_CREATE:
RECT rcClient; // dimensions of client area
// handle to tree-view control
// Ensure that the common control DLL is loaded.
InitCommonControls();
// Get the dimensions of the parent window's client area, and create
// the tree-view control.
GetClientRect(hWnd, &rcClient);
hwndTV = CreateWindowEx(0,
WC_TREEVIEW,
TEXT("Tree View"),
WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES,
0,
0,
rcClient.right,
rcClient.bottom,
hWnd,
(HMENU)ID_TREEVIEW,
hInst,
NULL);
// Initialize the image list, and add items to the control.
// InitTreeViewImageLists and InitTreeViewItems are application-
// defined functions, shown later.
if (!InitTreeViewItems(hwndTV))
{
DestroyWindow(hwndTV);
return FALSE;
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDC_MAIN_BUTTON:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
//TreeView_EnsureVisible(hwndTV,hti);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_NOTIFY:
{
LPNMTREEVIEW pnm = (LPNMTREEVIEW)lParam;
if (pnm->hdr.code == NM_CUSTOMDRAW)
{
//LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
//TreeView_GetItem(
//pnm->iItem
LPNMTVCUSTOMDRAW lplvcd = (LPNMTVCUSTOMDRAW)lParam;
//pnm->iItem
//TreeView_GetItem(hWnd,pnm->iItem);
switch (lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT :
return CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
if(found_unMatched(lplvcd->nmcd.lItemlParam))
{
hwndTree = GetDlgItem(hWnd,ID_TREEVIEW);
lplvcd->clrText = RGB(0, 255,0);
ZeroMemory(&tv, sizeof(TVITEM));
tv.hItem=(HTREEITEM)lplvcd->nmcd.dwItemSpec;
tv.mask=TVIF_TEXT|TVIF_HANDLE;
tv.cchTextMax=100;
tv.pszText=(LPWSTR)achBuf;
if(TreeView_GetItem(hwndTree,&tv))
{
achBuf;
}
hChild =(HTREEITEM)TreeView_GetChild(hwndTree,(HTREEITEM)lplvcd->nmcd.dwItemSpec);
hSibling=(HTREEITEM)TreeView_GetNextSibling(hwndTree,hChild);
}
return CDRF_NOTIFYSUBITEMDRAW;
break;
case CDDS_POSTPAINT:
return CDRF_DODEFAULT;
break;
case CDDS_ITEMPOSTPAINT| CDDS_SUBITEM :
hwndTree = GetDlgItem(hWnd,ID_TREEVIEW);
ZeroMemory(&tv, sizeof(TVITEM));
tv.hItem=(HTREEITEM)lplvcd->nmcd.dwItemSpec;
tv.mask=TVIF_TEXT|TVIF_HANDLE;
tv.cchTextMax=100;
tv.pszText=(LPWSTR)achBuf;
if(TreeView_GetItem(hwndTree,&tv))
{
achBuf;
}
if((HTREEITEM)lplvcd->nmcd.dwItemSpec==hSibling)
{
lplvcd->clrText = RGB(176, 0,0);
}
return CDRF_NEWFONT;
break;
case CDDS_ITEMPOSTPAINT:
double_click=1;
break;
}
}}break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
this will color my parent node but child nodes(subitem) remained default(black) and return CDRF_NOTIFYSUBITEMDRAW didnt work. Please help!!!

how can I set static controls background color programmatically

I want to change label background color within a function, I tried this code but nothing changed after calling changecolor function
HWND hWndLabel;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
hWndLabel = CreateWindowEx(WS_EX_TRANSPARENT,
L"STATIC", L"", WS_CHILD | WS_VISIBLE | SS_LEFT | WS_SYSMENU,
75, 75, 70, 70, hWnd, (HMENU)labelId, hInst, NULL);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND: // all events are handled here
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
DWORD WINAPI changecolor(){
HDC hdc = GetDC(hWndLabel); // get context
SetBkColor(hdc, RGB(0, 0, 230)); // Code Copied from the above answer by cpx.
return 0;
}
I read that Static controls send their parent a WM_CTLCOLORSTATIC message just before they paint themselves. code is implemented within CALLBACK function, but where this code is called (changing color)?, how can I call SetTextColor within a function
code example :
case WM_CTLCOLORSTATIC:
if (the_button_was_clicked) {
HDC hdc = reinterpret_cast<HDC>(wParam);
SetTextColor(hdc, COLORREF(0xFF, 0x00, 0x00));
}
return ::GetSysColorBrush(COLOR_WINDOW); // example color, adjust for your circumstance
Try something more like this:
HWND hWndLabel;
HBRUSH hBrushLabel;
COLORREF clrLabelText;
COLORREF clrLabelBkGnd;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
hWndLabel = CreateWindowEx(0, L"STATIC", L"", WS_CHILD | WS_VISIBLE | SS_LEFT,
75, 75, 70, 70, hWnd, (HMENU)labelId, hInst, NULL);
hBrushLabel = NULL;
clrLabelText = GetSysColor(COLOR_WINDOWTEXT);
clrLabelBkGnd = GetSysColor(COLOR_WINDOW);
break;
case WM_DESTROY:
if (hBrushLabel) DeleteObject(hBrushLabel);
PostQuitMessage(0);
break;
case WM_CTLCOLORSTATIC: {
HDC hdc = reinterpret_cast<HDC>(wParam);
SetTextColor(hdc, clrLabelText);
SetBkColor(hdc, clrLabelBkGnd);
if (!hBrushLabel) hBrushLabel = CreateSolidBrush(clrLabelBkGnd);
return reinterpret_cast<LRESULT>(hBrushLabel);
}
case WM_COMMAND: // all events are handled here
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
DWORD WINAPI changecolor()
{
if (hBrushLabel) {
DeleteObject(hBrushLabel);
hBrushLabel = NULL;
}
clrLabelText = RGB(0xFF, 0x00, 0x00);
clrLabelBkGnd = RGB(0, 0, 230);
InvalidateRect(hWndLabel, NULL, TRUE);
return 0;
}
There is a similar example in the WM_CTLCOLORSTATIC documentation.
The following C++ example shows how to set the text foreground and background colors of a static control in response to the WM_CTLCOLORSTATIC message. The hbrBkgnd variable is a static HBRUSH variable that is initialized to NULL, and stores the background brush between calls to WM_CTLCOLORSTATIC. The brush must be destroyed by a call to the DeleteObject function when it is no longer needed, typically when the associated dialog box is destroyed.
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC) wParam;
SetTextColor(hdcStatic, RGB(255,255,255));
SetBkColor(hdcStatic, RGB(0,0,0));
if (hbrBkgnd == NULL)
{
hbrBkgnd = CreateSolidBrush(RGB(0,0,0));
}
return (INT_PTR)hbrBkgnd;
}

Resources