It is normal, in TabControlProc, you paint over the whole Tab Control
You can check with Spy++ that it is behind
What are you trying to do ?
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
WinMain.cpp:
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0601 // Target Windows 7 or later
#define WIN_32_EXTRA_LEAN
#define UNICODE
#define _UNICODE
#include "glad/glad.h"
#include <Windows.h>
#include <commctrl.h>
#include <windowsx.h>
#include <iostream>
#include <utility>
#include "Application.h"
#include "OpenGLDefinitions.h"
int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int);
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
bool SetPixelFormatForContext(HDC hdc, BYTE colorBits = 24, BYTE depthBits = 32, BYTE stencilBits = 8);
WNDCLASSEX RegisterWindowClasses(HINSTANCE hinstance);
std::pair<int, int> GetScreenDimensions();
HGLRC CreateOpenGLContext(HDC hdc, const int* attribList = nullptr);
bool EnableVSync(HDC hdc);
void isGLADInit();
#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, "comctl32.lib")
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
Application* gApplication = nullptr;
GLuint gVertexArrayObject = 0;
std::pair<int, int> GetScreenDimensions() {
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
return std::make_pair(screenWidth, screenHeight);
}
void isGLADInit() {
if (!gladLoadGL())
{
std::cout << "Could not initialize GLAD \n";
}
else {
std::cout << "OpenGL Version " << GLVersion.major << std::endl;
}
}
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int ICmdShow) {
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&icex);
gApplication = new Application();
WNDCLASSEX mainWndClass = RegisterWindowClasses(hinstance);
std::pair<int, int> screenDimensions = GetScreenDimensions();
int ScreenWidth = screenDimensions.first;
int ScreenHeight = screenDimensions.second;
int clientWidth = 800;
int clientHeight = 600;
RECT windowRect;
SetRect(&windowRect, (ScreenWidth / 2) - (clientWidth / 2),
(ScreenHeight / 2) - (clientHeight / 2),
(ScreenWidth / 2) + (clientWidth / 2),
(ScreenHeight / 2) + (clientHeight / 2));
DWORD mainWindowStyle = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME);
AdjustWindowRectEx(&windowRect, mainWindowStyle, FALSE, 0);
const wchar_t windowName[] = "Win32 Tab Window";
HWND hwndMainWindow = CreateWindowEx(0, mainWndClass.lpszClassName, windowName, mainWindowStyle,
windowRect.left, windowRect.top, windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top, NULL, NULL, hinstance, szCmdLine);
HDC hdcMainWindow = GetDC(hwndMainWindow);
if (!SetPixelFormatForContext(hdcMainWindow)) {
std::cerr << "Error setting pixel format for the device context." << std::endl;
return -1;
}
ShowWindow(hwndMainWindow, SW_SHOW);
UpdateWindow(hwndMainWindow);
gApplication->Initialize();
int vsynch = 0; // Default to no vsync
DWORD lastTick = GetTickCount();
MSG msg;
while (true) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DWORD thisTick = GetTickCount();
float dt = float(thisTick - lastTick) * 0.001f;
lastTick = thisTick;
if (gApplication != nullptr) {
gApplication->Update(dt);
RECT clientRect;
GetClientRect(hwndMainWindow, &clientRect);
clientWidth = clientRect.right - clientRect.left;
clientHeight = clientRect.bottom - clientRect.top;
}
}
if (gApplication != nullptr) {
std::cout << "Expected application to be null on exit \n";
delete gApplication;
}
return (int)msg.wParam;
}
WndProc.cpp:
#include <Windows.h>
#include <commctrl.h>
#include <windowsx.h>
#include <iostream>
#include "Application.h"
#include "WndProc.h"
#include "glad/glad.h"
extern Application* gApplication;
extern GLuint gVertexArrayObject;
HWND hTabControl = nullptr; // Handle to the Tab control
WNDPROC gOriginalTabProc = nullptr; // Global variable to store the original Tab Control procedure
LRESULT CALLBACK TabControlProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
switch (iMsg) {
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// Get the client area of the Tab Control
RECT clientRect;
GetClientRect(hwnd, &clientRect);
// Set a background color
HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255)); // White background
FillRect(hdc, &clientRect, hBrush);
DeleteObject(hBrush);
// Draw a cross in the Tab Control's client area
HPEN hPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255)); // Blue cross
SelectObject(hdc, hPen);
MoveToEx(hdc, clientRect.left, clientRect.top, nullptr);
LineTo(hdc, clientRect.right, clientRect.bottom);
MoveToEx(hdc, clientRect.right, clientRect.top, nullptr);
LineTo(hdc, clientRect.left, clientRect.bottom);
DeleteObject(hPen);
EndPaint(hwnd, &ps);
return 0;
}
}
// Forward unhandled messages to the original Tab Control procedure
return CallWindowProc(gOriginalTabProc, hwnd, iMsg, wParam, lParam);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
switch (iMsg) {
case WM_CREATE: {
std::cout << "Window created successfully! \n";
// Create the Tab Control
hTabControl = CreateWindowEx(
0, WC_TABCONTROL, nullptr,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
0, 0, 0, 0, // Initial size will be adjusted later
hwnd, nullptr, GetModuleHandle(nullptr), nullptr
);
if (!hTabControl) {
std::cerr << "Failed to create Tab control.\n";
}
// Add a tab
TCITEM tie;
tie.mask = TCIF_TEXT;
tie.pszText = const_cast<LPWSTR>(L"Tab 1");
SendMessage(hTabControl, TCM_INSERTITEM, 0, (LPARAM)&tie);
// Subclass the Tab Control
gOriginalTabProc = (WNDPROC)SetWindowLongPtr(hTabControl, GWLP_WNDPROC, (LONG_PTR)TabControlProc);
break;
}
case WM_SIZE: {
// Resize the Tab control to fill the client area
if (hTabControl) {
RECT clientRect;
GetClientRect(hwnd, &clientRect);
MoveWindow(hTabControl, 0, 0, clientRect.right, clientRect.bottom, TRUE);
}
break;
}
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// Draw a cross in the client area of the Tab control
if (hTabControl) {
RECT clientRect;
GetClientRect(hTabControl, &clientRect);
// Set a background color
HBRUSH hBrush = CreateSolidBrush(RGB(200, 200, 200));
FillRect(hdc, &clientRect, hBrush);
DeleteObject(hBrush);
// Draw a cross
HPEN hPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
SelectObject(hdc, hPen);
MoveToEx(hdc, clientRect.left, clientRect.top, nullptr);
LineTo(hdc, clientRect.right, clientRect.bottom);
MoveToEx(hdc, clientRect.right, clientRect.top, nullptr);
LineTo(hdc, clientRect.left, clientRect.bottom);
DeleteObject(hPen);
}
EndPaint(hwnd, &ps);
break;
}
case WM_CLOSE:
if (gApplication != nullptr) {
gApplication->Shutdown();
delete gApplication;
gApplication = nullptr;
DestroyWindow(hwnd);
}
else {
std::cout << "Already shut down! \n";
}
break;
case WM_DESTROY:
if (gVertexArrayObject != 0) {
HDC hdc = GetDC(hwnd);
HGLRC hglrc = wglGetCurrentContext();
glBindVertexArray(0);
glDeleteVertexArrays(1, &gVertexArrayObject);
gVertexArrayObject = 0;
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hglrc);
ReleaseDC(hwnd, hdc);
PostQuitMessage(0);
}
else {
std::cout << "Multiple destroy messages \n";
}
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
I no longer see the Tab and text string ID in the upper left of the window like I did before adding the code to paint the 'x'. Where did the tab control go?
So far there is an output in the console window that "Multiple destroy messages" are taking place. Is that relevant to the tab visibility problem that is going on?
So far as I know the client area of the tab is being recieved to draw to so it seems that currently the client area is looking too large and would be drawing over the tab currently. It seems if I turn off the drawing code the Tab still isn't visible in the client area of the window which will appear on my system with a gray background color.
The functions that were not included in this post came from:
https://github.com/Eversmile12/OpenGLGLAD
as far as the OpenGL bootstrapping and the RegisterWindowClass function...
It is normal, in TabControlProc, you paint over the whole Tab Control
You can check with Spy++ that it is behind
What are you trying to do ?