Here is a small app that I threw together to demonstrate the problem visually...
It creates a menubar(file, edit, help etc), a button toolbar and a status bar inside the gdk window. The menubar is correctly placed as its placed into the window with an api function SetMenu..
The status bar and toolbar are created with CreateWindowEx and work differently, resize the window to see the problem, as you drag it, the toolbar and status bar will flicker through to the top.
Here is the code for the main program, note that if you want to compile this, you will need to add a resource menu to your program called IDC_MAINMENUBAR :
// NOTE : Alot of the variables in here are not required for this app, some of the callbacks and class registration
// functions are not needed either, this little prog is essentially cut and pasted from another program of mine
// to demonstrate the problem in a visible way.
#include <windows.h> // included so we can use the windows API
#include <commctrl.h>
#include <uxtheme.h>
#include "DarkGDK.h"
#include "resource.h" // vs produced resource header file
#include "globstruct.h" // gdk globals to get windows handle
#include "stdio.h"
#ifdef STRICT
WNDPROC lpPrevWndProc;
#else
FARPROC lpPrevWndProc;
#endif
// defines for the windows controls
#define IDC_MAIN_TOOL 102
#define IDC_MAIN_STATUS 103
// defines for display mode - this is the messy way ;) - I prefer not to use defines unless i have to.. preprocessors
// can do strange things sometimes. Although its generally safe to use it like this with a simple number, but when
// you get into the definition of parts of functions etc it can get messy and is dependant on the preprocessor
// working how you think it will....
#define DISPLAYWIDTH 1024
#define DISPLAYHEIGHT 768
#define DISPLAYDEPTH 32
LRESULT APIENTRY MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MDIChildWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL SetUpMDIChildWindowClass(HINSTANCE hInstance);
HWND CreateNewMDIChild(HWND hMDIClient);
MSG Msg;
HWND g_hMDIClient = NULL;
HWND g_hMainWindow = NULL;
HWND hStatus = NULL;
HMENU g_pMainMenu = NULL;
HCURSOR g_pCursor = NULL;
HWND hTool;
TBBUTTON tbb[3];
TBBUTTON butObjEdit[2];
TBBUTTON butTools[8];
TBBUTTON butSpacer[2];
TBADDBITMAP tbab;
TBADDBITMAP mybut;
HBITMAP hBMP;
POINT pt;
RECT rc;
CLIENTCREATESTRUCT ccs;
const char g_szClassName[] = "myWindowClass";
const char g_szChildClassName[] = "myMDIChildWindowClass";
int statwidths[] = {100, -1};
bool g_bExit = false;
// the main entry point for the application is this function
void DarkGDK ( void )
{
// this isnt needed really, its from the MDI part of the app this snip came from
InitCommonControls(); // MUST be called BEFORE ANY calls are made to ANYTHING RELATED to common controls.
// INIT GDK
dbSyncOn ( );
dbSyncRate ( 60 );
dbSetDisplayMode(DISPLAYWIDTH, DISPLAYHEIGHT, DISPLAYDEPTH);
////////////////////////////////////////////////////////////////
// START WinAPI Initialization
///////////////////////////////////////////////////////////////
// TOOL AND STATUS CREATION START
g_hMainWindow = g_pGlob->hWnd;
// Initialize main window's menu, messagebox if it fails
g_pMainMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MAINMENUBAR));
if(!g_pMainMenu)
{
MessageBox(NULL, "Fatal Error! Could not load the menu resource!","*",MB_OK);
return;
}
// set our menu here after the actual window has been initialized
if(!SetMenu(g_pGlob->hWnd, g_pMainMenu))
{
MessageBox(NULL, "Fatal Error! Could not create the menu !","*",MB_OK);
return;
}
// NOTE : These are being left deliberately WHERE THEY ARE MADE, in relation to window
// layers, to demonstrate the problem, I can send them constantly to the front by
// either creating them with the appropriate flag or sending the appropriate message
// each game loop
/////////////////////////////////////////////////////////////////////////////////
// Create Toolbar
hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, CCS_ADJUSTABLE | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
g_hMainWindow, (HMENU)IDC_MAIN_TOOL, GetModuleHandle(NULL), NULL);
if(hTool == NULL)
MessageBox(g_hMainWindow, "Could not create tool bar.", "Error", MB_OK | MB_ICONERROR);
// Send the TB_BUTTONSTRUCTSIZE message, which is required for
// backward compatibility.
SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
tbab.hInst = HINST_COMMCTRL;
tbab.nID = IDB_STD_SMALL_COLOR;
//SendMessage(hTool, TB_SETBITMAPSIZE, 0, (LPARAM)MAKELONG(16,16) );
SendMessage(hTool, TB_ADDBITMAP, 16, (LPARAM)&tbab);
ZeroMemory(tbb, sizeof(tbb));
tbb[0].iBitmap = STD_FILENEW;
tbb[0].fsState = TBSTATE_ENABLED;
tbb[0].fsStyle = TBSTYLE_BUTTON;
tbb[0].idCommand = ID_FILE_NOTHING;
//tbb[0].iString = (int)"NEW";
tbb[1].iBitmap = STD_FILEOPEN;
tbb[1].fsState = TBSTATE_ENABLED;
tbb[1].fsStyle = TBSTYLE_BUTTON;
tbb[1].idCommand = ID_FILE_NOTHING;
//tbb[1].iString = (int)"OPEN";
tbb[2].iBitmap = STD_FILESAVE;
tbb[2].fsState = TBSTATE_ENABLED;
tbb[2].fsStyle = TBSTYLE_BUTTON;
tbb[2].idCommand = ID_FILE_NOTHING;
//tbb[2].iString = (int)"SaveAs";
SendMessage(hTool, TB_ADDBITMAP, 0, (LPARAM)&mybut);
ZeroMemory(butObjEdit, sizeof(butObjEdit));
butObjEdit[0].iBitmap = 4;
butObjEdit[0].fsState = TBSTATE_ENABLED;
butObjEdit[0].fsStyle = TBSTYLE_BUTTON;
butObjEdit[0].idCommand = ID_FILE_NOTHING;
butObjEdit[1].iBitmap = 5;
butObjEdit[1].fsState = TBSTATE_ENABLED;
butObjEdit[1].fsStyle = TBSTYLE_BUTTON;
butObjEdit[1].idCommand = ID_FILE_NOTHING;
SendMessage(hTool, TB_ADDBUTTONS, sizeof(tbb)/sizeof(TBBUTTON), (LPARAM)&tbb);
SendMessage(hTool, TB_ADDBUTTONS, sizeof(butObjEdit)/sizeof(TBBUTTON), (LPARAM)&butObjEdit);
///////////////////////////////////////////////////////////////////////////////////////
// Create Status bar
hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL,
WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0,
g_hMainWindow, (HMENU)IDC_MAIN_STATUS, GetModuleHandle(NULL), NULL);
SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"STATUS BAR");
// END TOOL AND STATUS
////////////////////////////////////////////////////////////////
// declare our callback function
lpPrevWndProc = (WNDPROC)SetWindowLong(g_pGlob->hWnd, GWL_WNDPROC, (LONG)MainWndProc);
// these arent needed, they are here from me playing with the window theme in another app
DWORD dwFlags = (STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS);
SetThemeAppProperties(dwFlags);
// END WinAPI Initialization
////////////////////////////////////////////////////////////////
// put our GDK window in the middle of the screen
SetWindowPos(g_pGlob->hWnd, NULL, GetSystemMetrics(SM_CXSCREEN)/2-(DISPLAYWIDTH/2),
GetSystemMetrics(SM_CYSCREEN)/2-(DISPLAYHEIGHT/2), DISPLAYWIDTH, DISPLAYHEIGHT, SWP_NOZORDER);
// I HAVE TRIED INITIALIZING GDK BOTH BEFORE AND AFTER THE WINDOWS CONTROLS AND IT MAKES NO DIFFERENCE
// turn on sync rate and set maximum rate to 60 fps
//dbSyncOn ( );
//dbSyncRate ( 60 );
//dbSetDisplayMode(DISPLAYWIDTH, DISPLAYHEIGHT, DISPLAYDEPTH);
dbMakeObjectCube(1, 2.0);
dbPositionObject(1, 0, 0, 20);
// our main loop
while ( LoopGDK ( ) )
{
dbRotateObject(1, dbObjectAngleX(1)+1.0, dbObjectAngleY(1)+1.0, dbObjectAngleZ(1)+1.0);
dbText(0, 0, "Arrow Keys to Move Camera... Resize the window to see the problem of the toolbar/statusbar, it will cover this text :(");
dbControlCameraUsingArrowKeys(0, 2.0, 2.0);
// exit if the app's global var tells us to, here to exit from the menu/toolbar etc
if(g_bExit)
{
return;
}
// update the screen
dbSync ( );
}
// return back to windows
return;
}
LRESULT APIENTRY MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SIZE:
{
HWND hTool;
RECT rcTool;
int iToolHeight;
HWND hStatus;
RECT rcStatus;
int iStatusHeight;
// Size toolbar and get height
hTool = GetDlgItem(hwnd, IDC_MAIN_TOOL);
SendMessage(hTool, TB_AUTOSIZE, 0, 0);
GetWindowRect(hTool, &rcTool);
iToolHeight = rcTool.bottom - rcTool.top;
// Size status bar and get height
hStatus = GetDlgItem(hwnd, IDC_MAIN_STATUS);
SendMessage(hStatus, WM_SIZE, 0, 0);
GetWindowRect(hStatus, &rcStatus);
iStatusHeight = rcStatus.bottom - rcStatus.top;
}
break;
case WM_SETCURSOR:
break;
case WM_DESTROY:
//DestroyWindow(g_hToolbar);
PostQuitMessage(0);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_FILE_EXIT:
g_bExit = true;
break;
default:
break;
}
return 0;
default:
break;
}
//return DefFrameProc(g_hMainWindow, NULL, uMsg, wParam, lParam);
return CallWindowProc(lpPrevWndProc, hwnd, uMsg, wParam, lParam);
}
If it ain't broke.... DONT FIX IT !!!