Adding Text to the Frame Of a Dialog
-
A CStatic is pretty straight forward to use for displaying text, but if you need a bitmap you can put that in a CStatic control as well. See here[^] for an example.
"the debugger doesn't tell me anything because this code compiles just fine" - random QA comment "Facebook is where you tell lies to your friends. Twitter is where you tell the truth to strangers." - chriselst "I don't drink any more... then again, I don't drink any less." - Mike Mullikins uncle
-
Hi The Frame of my Dialog has about 1.5" to 2" (I find it difficult to talk in pixels) It seem like a nice enough area to add Text Rather than using a CStatic object and CTEXT/LTEXT resource item would processing a NCLIENT message and some how inserting a bitmap (maybe I making problems for myself) work ?
You should be able to do it from the WM_NCPAINT call which will give you the DC to place a bitmap or text in. You will probably have to subclass the window (which means holding the current window handler) because you will probably need to call the current handler then effectively draw over the top of everything. I think if you just do your drawing and drop thru the existing handler will overwrite whatever you put on the DC. Don't forget if you use text to set the background to transparent otherwise you will get a white box background where the text is. If you need to search for stuff technically what you are doing is skinning a dialog box.
In vino veritas
-
Hi The Frame of my Dialog has about 1.5" to 2" (I find it difficult to talk in pixels) It seem like a nice enough area to add Text Rather than using a CStatic object and CTEXT/LTEXT resource item would processing a NCLIENT message and some how inserting a bitmap (maybe I making problems for myself) work ?
-
You should be able to do it from the WM_NCPAINT call which will give you the DC to place a bitmap or text in. You will probably have to subclass the window (which means holding the current window handler) because you will probably need to call the current handler then effectively draw over the top of everything. I think if you just do your drawing and drop thru the existing handler will overwrite whatever you put on the DC. Don't forget if you use text to set the background to transparent otherwise you will get a white box background where the text is. If you need to search for stuff technically what you are doing is skinning a dialog box.
In vino veritas
Hi A couple of questions First what call do I use to get the DC of the non-client area GetDc GetWindowDC GetDcEx Second in my message handler the first thing I should is call the default handler CWnd::OnNcPaint Calling it at the end will wipe out whatever I have done correct ?
-
Hi A couple of questions First what call do I use to get the DC of the non-client area GetDc GetWindowDC GetDcEx Second in my message handler the first thing I should is call the default handler CWnd::OnNcPaint Calling it at the end will wipe out whatever I have done correct ?
ForNow wrote:
Second in my message handler the first thing I should is call the default handler CWnd::OnNcPaint Calling it at the end will wipe out whatever I have done correct ?
Seems like the best answer to this is to just try it and see.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
-
Hi A couple of questions First what call do I use to get the DC of the non-client area GetDc GetWindowDC GetDcEx Second in my message handler the first thing I should is call the default handler CWnd::OnNcPaint Calling it at the end will wipe out whatever I have done correct ?
As always MSDN is the authoritive answer on that WM_NCPAINT message (Windows)[^] Quote: "The wParam value can be passed to GetDCEx as in the following example." You need GetWindowLongPtr with index DWLP_DLGPROC to get the current dialog handler which you probably hold from WM_INITDIALOG. You use CallWindowProc with the held original handler to call the original handler when you need it. Can I offer you a routine to Safely get the dialog procedure because you can get caught with unicode/non unicode dialog windows, that is determined by the function called in the dialog creation and you can have both in the same application.
WNDPROC SafeGetDialogProc(HWND hwnd)
{
if(IsWindowUnicode(hwnd))
return (WNDPROC)GetWindowLongPtrW(hwnd, DWLP_DLGPROC);
else
return (WNDPROC)GetWindowLongPtrA(hwnd, DWLP_DLGPROC);
}In your case you will call the old handler from within NC_PAINT and then do your special drawing routines over what they did and return zero as is required as you processed the call. Here is a code hack to start with (the handler should really only be retrieved once at WM_INITDIALOG just for speed)
case WM_NCPAINT: {
WNDPROC OldHandler = SafeGetDialogProc(hwnd); // Get dialog handler
CallWindowProc(OldHandler, hwnd, Msg, wParam, lParam); // Call old handler// Do your special draw stuff return(0); // Return zero }
In vino veritas
-
As always MSDN is the authoritive answer on that WM_NCPAINT message (Windows)[^] Quote: "The wParam value can be passed to GetDCEx as in the following example." You need GetWindowLongPtr with index DWLP_DLGPROC to get the current dialog handler which you probably hold from WM_INITDIALOG. You use CallWindowProc with the held original handler to call the original handler when you need it. Can I offer you a routine to Safely get the dialog procedure because you can get caught with unicode/non unicode dialog windows, that is determined by the function called in the dialog creation and you can have both in the same application.
WNDPROC SafeGetDialogProc(HWND hwnd)
{
if(IsWindowUnicode(hwnd))
return (WNDPROC)GetWindowLongPtrW(hwnd, DWLP_DLGPROC);
else
return (WNDPROC)GetWindowLongPtrA(hwnd, DWLP_DLGPROC);
}In your case you will call the old handler from within NC_PAINT and then do your special drawing routines over what they did and return zero as is required as you processed the call. Here is a code hack to start with (the handler should really only be retrieved once at WM_INITDIALOG just for speed)
case WM_NCPAINT: {
WNDPROC OldHandler = SafeGetDialogProc(hwnd); // Get dialog handler
CallWindowProc(OldHandler, hwnd, Msg, wParam, lParam); // Call old handler// Do your special draw stuff return(0); // Return zero }
In vino veritas
It's in middle of the night here I'll try it in the morning In win32 version of WM_NCPAINT wparam has the HRGN value of the NC area no such information with MFC I did try to draw a bitmap with CStatic::SetBitMap all it did was draw a rectangle box I'll get back to this in the morning thanks
-
As always MSDN is the authoritive answer on that WM_NCPAINT message (Windows)[^] Quote: "The wParam value can be passed to GetDCEx as in the following example." You need GetWindowLongPtr with index DWLP_DLGPROC to get the current dialog handler which you probably hold from WM_INITDIALOG. You use CallWindowProc with the held original handler to call the original handler when you need it. Can I offer you a routine to Safely get the dialog procedure because you can get caught with unicode/non unicode dialog windows, that is determined by the function called in the dialog creation and you can have both in the same application.
WNDPROC SafeGetDialogProc(HWND hwnd)
{
if(IsWindowUnicode(hwnd))
return (WNDPROC)GetWindowLongPtrW(hwnd, DWLP_DLGPROC);
else
return (WNDPROC)GetWindowLongPtrA(hwnd, DWLP_DLGPROC);
}In your case you will call the old handler from within NC_PAINT and then do your special drawing routines over what they did and return zero as is required as you processed the call. Here is a code hack to start with (the handler should really only be retrieved once at WM_INITDIALOG just for speed)
case WM_NCPAINT: {
WNDPROC OldHandler = SafeGetDialogProc(hwnd); // Get dialog handler
CallWindowProc(OldHandler, hwnd, Msg, wParam, lParam); // Call old handler// Do your special draw stuff return(0); // Return zero }
In vino veritas
-
It's in middle of the night here I'll try it in the morning In win32 version of WM_NCPAINT wparam has the HRGN value of the NC area no such information with MFC I did try to draw a bitmap with CStatic::SetBitMap all it did was draw a rectangle box I'll get back to this in the morning thanks
GetDCEx expects a HRGN which as you said is in the wParam and gives you back the DC.
HDC hdc;
hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);Also remember that returned DC is a screen DC so you have to BitBlt the bitmap onto it to display anything, simply selecting the bitmap onto it will do nothing other than attach a pointer. The fact you got the white box makes me think you didn't do it right so lets give you the basics, which go like this SETUP (usually in WM_INITDIALOG):
HBITMAP hBmp; // This needs to be held somewhere for life of dialog or global
HDC hMemDC; // This is the same it needs to be held somewhere for life of dialog or globalhBmp = (HBITMAP) LoadImage(0, "SomeName.Bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); // Load bitmap file
hMemDC = CreateCompatibleDC(NULL); // Create memory device context
if (hMemDC) SelectObject(hMemDC, hBmp); // Select the bitmap to any valid memory context// Optional stuff you might want the loaded bitmap dimensions
BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm); // Get object data
BmpWth = bm.bmWidth; // Get and hold bitmap width to some dialog life variable
BmpHt = bm.bmHeight; // Get and hold bitmap height to some dialog life variableUSE (NC_PAINT):
HDC hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN); // Get DC
BitBlt(hdc, ???, ???, BmpWth, BmpHt, hMemDC, 0, 0, SRCCOPY); // Transfer bitmap ... ??? are co-ords where to placeCLEANUP (usually WM_DESTROY):
DeleteObject(hBmp); // Release loaded bitmap
DeleteDC(hMemDC); // Release the memory context created aboveFinally if you want to add buttons etc there are a few more tricks and I will refer you to an article Custom Titlebar | Catch22[^]
In vino veritas
-
GetDCEx expects a HRGN which as you said is in the wParam and gives you back the DC.
HDC hdc;
hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);Also remember that returned DC is a screen DC so you have to BitBlt the bitmap onto it to display anything, simply selecting the bitmap onto it will do nothing other than attach a pointer. The fact you got the white box makes me think you didn't do it right so lets give you the basics, which go like this SETUP (usually in WM_INITDIALOG):
HBITMAP hBmp; // This needs to be held somewhere for life of dialog or global
HDC hMemDC; // This is the same it needs to be held somewhere for life of dialog or globalhBmp = (HBITMAP) LoadImage(0, "SomeName.Bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); // Load bitmap file
hMemDC = CreateCompatibleDC(NULL); // Create memory device context
if (hMemDC) SelectObject(hMemDC, hBmp); // Select the bitmap to any valid memory context// Optional stuff you might want the loaded bitmap dimensions
BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm); // Get object data
BmpWth = bm.bmWidth; // Get and hold bitmap width to some dialog life variable
BmpHt = bm.bmHeight; // Get and hold bitmap height to some dialog life variableUSE (NC_PAINT):
HDC hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN); // Get DC
BitBlt(hdc, ???, ???, BmpWth, BmpHt, hMemDC, 0, 0, SRCCOPY); // Transfer bitmap ... ??? are co-ords where to placeCLEANUP (usually WM_DESTROY):
DeleteObject(hBmp); // Release loaded bitmap
DeleteDC(hMemDC); // Release the memory context created aboveFinally if you want to add buttons etc there are a few more tricks and I will refer you to an article Custom Titlebar | Catch22[^]
In vino veritas