famatto

New Member
Joined
Mar 10, 2024
Messages
1
```
#include <Windows.h>
#include <Richedit.h>


HWND hwnd;
HWND panel;
HWND richEdit;
WNDPROC oldStaticProc;

int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int);
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK StaticProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

#if _DEBUG
#pragma comment( linker, "/subsystem:console" )
int main(int argc, const char** argv) {
return WinMain(GetModuleHandle(NULL), NULL, GetCommandLineA(), SW_SHOWDEFAULT);
}
#else
#pragma comment( linker, "/subsystem:windows" )
#endif
#pragma comment(lib, "opengl32.lib")

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
LoadLibrary(TEXT("Msftedit.dll"));
int width = 800;
int height = 600;

WNDCLASS wc = { };
const wchar_t* CLASS_NAME = L"OpenGL and RichEdit Message Processing";
wc.lpfnWndProc = WindowProcedure;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;

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

hwnd = CreateWindowEx(
0,
CLASS_NAME,
L"OpenGL RichEdit Control",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, width, height,
NULL,
NULL,
hInstance,
NULL
);

if (hwnd == NULL)
{
MessageBox(NULL, L"Window Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
}
if (hwnd != NULL)
{
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
}
//GetClientRect(hwnd, &rect_hwnd);
panel = CreateWindowEx(
0,
L"STATIC",
NULL,
WS_CHILD | WS_VISIBLE,
0, height - 150, width, 150,
hwnd,
NULL,
hInstance,
NULL
);
InvalidateRect(panel, NULL, TRUE);
oldStaticProc = (WNDPROC)SetWindowLongPtr(panel, GWLP_WNDPROC, (LONG_PTR)StaticProc);

richEdit = CreateWindowEx(
WS_EX_CLIENTEDGE,
RICHEDIT_CLASS,
L"Type here...",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL,
0, 0, width, 150,
panel,
NULL,
hInstance,
NULL
);
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return 0;
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0));

switch (msg)
{
case WM_PAINT:
{
if (hwnd == panel) // only draw border for the panel
{

}
break;
}
case WM_CTLCOLORSTATIC:
{
//HDC hdcStatic = (HDC)wParam;
//SetBkColor(hdcStatic, RGB(0, 255, 0));
//return (INT_PTR)hBrush;
}
case WM_SIZE:
{
int width = LOWORD(lParam);
int height = HIWORD(lParam);

SetWindowPos(panel, NULL, 0, height - 150, width, 150, SWP_NOZORDER);
SetWindowPos(richEdit, NULL, 0, 0, width, 150, SWP_NOZORDER);

break;
}
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}

LRESULT CALLBACK StaticProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_ERASEBKGND:
// Prevent the background from being erased
return TRUE;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);

// Create a rectangle that is slightly smaller than the panel
RECT rect;
GetClientRect(hwnd, &rect);
rect.left += 2;
rect.top += 2;
rect.right -= 2;
rect.bottom -= 2;

// Create a pen (for drawing lines) that is red and 2 pixels wide
HPEN hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));

// Select the pen into the device context
HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);

// Draw a rectangle that is the same size as the panel
Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);

// Clean up: deselect the pen, delete it, and end the paint operation
SelectObject(hdc, hOldPen);
DeleteObject(hPen);
EndPaint(hwnd, &ps);
break;
default:
return CallWindowProc(oldStaticProc, hwnd, msg, wParam, lParam);
}
return 0;
}```


I would like to draw a border (1px black should be fine...) on the limits of panel and also I would like the background color of panel to be the color green. So far I have: ```
Severity Code Description Project File Line Suppression State Details
Warning C6387 'hwnd' could be '0': this does not adhere to the specification for the function 'UpdateWindow'. See line 58 for an earlier location where this can occur demo-win32 C:\Users\franc\source\repos\demo-win32\main.cpp 59```


What could be wrong here? How can I get the border and background color drawing in a way that is suitable to resizing of the window when maximized and also when the user drags the corner of the window or the side of the window with the mouse?
 


Solution
To draw a black border and set a green background for your panel window in your Win32 application, you'll need to handle the WM_PAINT message appropriately and make sure that the background color is set correctly for the panel. Here’s an adjusted version of your code:

Updated Code​

C++:
#include #include HWND hwnd; HWND panel; HWND richEdit; WNDPROC oldStaticProc; int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int); LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK StaticProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); #if _DEBUG #pragma comment( linker, "/subsystem:console" ) int main(int argc, const char** argv) { return WinMain(GetModuleHandle(NULL), NULL...
To draw a black border and set a green background for your panel window in your Win32 application, you'll need to handle the WM_PAINT message appropriately and make sure that the background color is set correctly for the panel. Here’s an adjusted version of your code:

Updated Code​

C++:
#include #include HWND hwnd; HWND panel; HWND richEdit; WNDPROC oldStaticProc; int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int); LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK StaticProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); #if _DEBUG #pragma comment( linker, "/subsystem:console" ) int main(int argc, const char** argv) { return WinMain(GetModuleHandle(NULL), NULL, GetCommandLineA(), SW_SHOWDEFAULT); } #else #pragma comment( linker, "/subsystem:windows" ) #endif #pragma comment(lib, "opengl32.lib") int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { LoadLibrary(TEXT("Msftedit.dll")); int width = 800; int height = 600; WNDCLASS wc = { }; const wchar_t* CLASS_NAME = L"OpenGL and RichEdit Message Processing"; wc.lpfnWndProc = WindowProcedure; wc.hInstance = hInstance; wc.hbrBackground = CreateSolidBrush(RGB(255, 255, 255)); // White background for the main window wc.lpszClassName = CLASS_NAME; if (!RegisterClass(&wc)) { MessageBox(NULL, L"Window Registration Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } hwnd = CreateWindowEx( 0, CLASS_NAME, L"OpenGL RichEdit Control", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL ); if (hwnd == NULL) { MessageBox(NULL, L"Window Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); panel = CreateWindowEx( 0, L"STATIC", NULL, WS_CHILD | WS_VISIBLE, 0, height - 150, width, 150, hwnd, NULL, hInstance, NULL ); oldStaticProc = (WNDPROC)SetWindowLongPtr(panel, GWLP_WNDPROC, (LONG_PTR)StaticProc); richEdit = CreateWindowEx( WS_EX_CLIENTEDGE, RICHEDIT_CLASS, L"Type here...", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, width, 150, panel, NULL, hInstance, NULL ); MSG msg = { }; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_SIZE: { int width = LOWORD(lParam); int height = HIWORD(lParam); SetWindowPos(panel, NULL, 0, height - 150, width, 150, SWP_NOZORDER); SetWindowPos(richEdit, NULL, 0, 0, width, 150, SWP_NOZORDER); break; } case WM_CLOSE: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } LRESULT CALLBACK StaticProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0)); // Green background switch (msg) { case WM_ERASEBKGND: return TRUE; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); RECT rect; GetClientRect(hwnd, &rect); FillRect(hdc, &rect, hBrush); // Create a rectangle that is slightly smaller than the panel rect.left += 1; rect.top += 1; rect.right -= 1; rect.bottom -= 1; HPEN hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); // Black pen for border HPEN hOldPen = (HPEN)SelectObject(hdc, hPen); HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH)); Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom); SelectObject(hdc, hOldPen); SelectObject(hdc, hOldBrush); DeleteObject(hPen); EndPaint(hwnd, &ps); return 0; } default: return CallWindowProc(oldStaticProc, hwnd, msg, wParam, lParam); } return 0; }

Explanation:​

  1. Background Color:
    • A static brush (HBRUSH) is created in the StaticProc to fill the background with green every time WM_PAINT is called.
    • FillRect is used to fill the background with the green brush.
    []Drawing Border:
    • A black HPEN is created within the WM_PAINT message handler to draw a 1-pixel wide border around the panel.
    • Rectangle is used to draw the border with the black pen.
    [
    ]Handling the Background:
    • WM_ERASEBKGND returns TRUE to prevent flickering by not allowing background erasure.
  2. Resizing:
    • The WM_SIZE message in WindowProcedure ensures that both the panel and richEdit controls are resized appropriately when the main window is resized.

      Note on Compiler Warning:​

      The compiler warning C6387 'hwnd' could be '0': ... indicates that UpdateWindow (or any other API) is used without verifying the successful creation of the hwnd. However, since we have checks and a message box for NULL checking immediately after the CreateWindowEx calls, this ensures that hwnd is correctly set before using UpdateWindow. This implementation should meet your requirements by drawing a green background and a black border around your panel, while also maintaining the desired resizing behavior.
 


Solution
Back
Top