Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / afsapplib / al_wizard.cpp
blobf26a578669ce79b020489a5dfec7a4f3f5e3c669
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
13 extern "C" {
14 #include <afs/param.h>
15 #include <afs/stds.h>
18 #include <WINNT/al_wizard.h>
22 * DEFINITIONS ________________________________________________________________
26 #define REFRESH_LEFT_PANE 0x00000001
27 #define REFRESH_RIGHT_PANE 0x00000002
29 #define cxRECT(_r) ((_r).right - (_r).left)
30 #define cyRECT(_r) ((_r).bottom - (_r).top)
32 #define clrWASH_SOLID RGB(0,0,128)
33 #define clrWASH_BRIGHTEST RGB(0,0,252)
34 #define clrWASH_DARKEST RGB(0,0,4)
35 #define clrWASH_INCREMENT RGB(0,0,4)
36 #define clrWASH_TEXT_BG RGB(0,0,0)
37 #define clrWASH_TEXT_FG RGB(255,255,255)
39 #define ToPALETTERGB(_rgb) PALETTERGB(GetRValue(_rgb),GetGValue(_rgb),GetBValue(_rgb))
41 #define cxLEFT_BACKGROUND 20
42 #define cxRIGHT_BACKGROUND 20
43 #define cyTOP_BACKGROUND 20
44 #define cyBOTTOM_BACKGROUND 20
46 #define xTEXT 30
47 #define yTEXT 30
48 #define cxSHADOW 2
49 #define cySHADOW 2
51 #define cptWASH_TEXT_SIZE 20
55 * PROTOTYPES _________________________________________________________________
59 static void MoveRect (RECT *_pr, LONG _dx, LONG _dy);
60 static void GetRectInParent (HWND hWnd, RECT *pr);
64 * ROUTINES ___________________________________________________________________
69 WIZARD::WIZARD (void)
71 m_iddTemplate = -1;
72 m_idcLeftPane = -1;
73 m_idcRightPane = -1;
74 m_idcBack = -1;
75 m_idcNext = -1;
76 m_idbGraphic16 = -1;
77 m_bmpGraphic16 = NULL;
78 m_idbGraphic256 = -1;
79 m_bmpGraphic256 = NULL;
80 m_palGraphic = NULL;
81 m_aStates = NULL;
82 m_cStates = 0;
83 m_stCurrent = -1;
84 m_fShowing = FALSE;
85 m_hWnd = NULL;
87 m_iddBackground = -1;
88 m_hBkg = NULL;
89 m_fBlue = TRUE;
90 m_fnBackground = NULL;
91 m_szBackground[0] = TEXT('\0');
92 m_bmpBackground = NULL;
93 m_pfnCallback = NULL;
94 m_bmpBuffer = NULL;
95 SetRectEmpty (&m_rBuffer);
97 HDC hdc = GetDC (NULL);
98 LOGFONT lf;
99 memset (&lf, 0x00, sizeof(lf));
100 GetObject (GetStockObject (DEFAULT_GUI_FONT), sizeof(lf), &lf);
101 lf.lfHeight = -MulDiv (cptWASH_TEXT_SIZE, GetDeviceCaps (hdc, LOGPIXELSY), 72);
102 lf.lfWidth = 0;
103 m_hfBackground = CreateFontIndirect (&lf);
104 ReleaseDC (NULL, hdc);
106 GeneratePalette();
110 WIZARD::~WIZARD (void)
112 if (m_hWnd && IsWindow (m_hWnd))
113 DestroyWindow (m_hWnd);
114 if (m_bmpGraphic16 != NULL)
115 DeleteObject (m_bmpGraphic16);
116 if (m_bmpGraphic256 != NULL)
117 DeleteObject (m_bmpGraphic256);
118 if (m_bmpBuffer != NULL)
119 DeleteObject (m_bmpBuffer);
120 if (m_palGraphic != NULL)
121 DeleteObject (m_palGraphic);
122 if (m_bmpBackground != NULL)
123 DeleteObject (m_bmpBackground);
124 if (m_hfBackground != NULL)
125 DeleteObject (m_hfBackground);
129 HWND WIZARD::GetWindow (void)
131 if (m_hWnd && IsWindow (m_hWnd))
132 return m_hWnd;
133 return NULL;
137 LPWIZARD WIZARD::GetWizard (HWND hWnd)
139 LPWIZARD pWiz = NULL;
141 try {
142 if ((pWiz = (LPWIZARD)GetWindowLongPtr (hWnd, DWLP_USER)) != NULL)
144 if ( (pWiz->m_hWnd != hWnd) && (pWiz->m_hBkg != hWnd) )
145 pWiz = NULL;
147 } catch(...) {
148 pWiz = NULL;
151 return pWiz;
155 void WIZARD::SetDialogTemplate (int iddTemplate, int idcLeftPane, int idcRightPane, int idcBack, int idcNext)
157 m_iddTemplate = iddTemplate;
158 m_idcLeftPane = idcLeftPane;
159 m_idcRightPane = idcRightPane;
160 m_idcBack = idcBack;
161 m_idcNext = idcNext;
163 if (m_fShowing)
165 Show (FALSE);
166 Show (TRUE);
171 void WIZARD::SetGraphic (int idbGraphic16, int idbGraphic256)
173 LPRGBQUAD pargb = NULL;
174 RGBQUAD argb[256];
176 m_idbGraphic16 = idbGraphic16;
177 m_idbGraphic256 = idbGraphic256;
179 if (m_bmpGraphic16 != NULL)
181 DeleteObject (m_bmpGraphic16);
182 m_bmpGraphic16 = NULL;
185 if (m_bmpGraphic256 != NULL)
187 DeleteObject (m_bmpGraphic256);
188 m_bmpGraphic256 = NULL;
191 if (m_palGraphic != NULL)
193 DeleteObject (m_palGraphic);
194 m_palGraphic = NULL;
197 m_bmpGraphic16 = (HBITMAP)TaLocale_LoadImage (idbGraphic16, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
199 if ((m_bmpGraphic256 = (HBITMAP)TaLocale_LoadImage (idbGraphic256, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION)) != NULL)
201 BITMAP bm;
202 GetObject (m_bmpGraphic256, sizeof(BITMAP), &bm);
204 if ((bm.bmBitsPixel * bm.bmPlanes) == 8)
206 HDC hdc = CreateCompatibleDC (NULL);
207 HBITMAP bmpOld = (HBITMAP)SelectObject (hdc, m_bmpGraphic256);
209 GetDIBColorTable (hdc, 0, 256, argb);
210 pargb = argb;
212 SelectObject (hdc, bmpOld);
213 DeleteDC (hdc);
217 GeneratePalette (pargb);
219 if (m_fShowing)
221 Refresh (REFRESH_LEFT_PANE);
226 void WIZARD::SetGraphicCallback (void (CALLBACK *pfnCallback)(LPWIZARD pWiz, HDC hdcTarget, LPRECT prTarget, HPALETTE hPal))
228 m_pfnCallback = pfnCallback;
230 if (m_fShowing)
232 Refresh (REFRESH_LEFT_PANE);
237 void WIZARD::SetStates (LPWIZARD_STATE aStates, size_t cStates)
239 m_aStates = aStates;
240 m_cStates = cStates;
242 if (m_fShowing)
244 Refresh (REFRESH_RIGHT_PANE);
249 int WIZARD::GetState (void)
251 return m_stCurrent;
255 void WIZARD::SetState (int stNew, BOOL fForce)
257 SendStateCommand (m_stCurrent, wcSTATE_LEAVE);
259 int stOriginal = m_stCurrent;
260 m_stCurrent = stNew;
262 if (!fForce && SendStateCommand (stNew, wcIS_STATE_DISABLED))
264 if (stOriginal <= stNew)
266 int st;
267 for (st = stNew+1; st < (int)m_cStates; ++st)
269 LPWIZARD_STATE pState;
270 if ((pState = FindState (st)) != NULL)
272 m_stCurrent = st;
273 if (!SendStateCommand (st, wcIS_STATE_DISABLED))
274 break;
275 m_stCurrent = stOriginal;
276 SendStateCommand (st, wcSTATE_ENTER);
277 SendStateCommand (st, wcSTATE_LEAVE);
280 stNew = (st < (int)m_cStates) ? st : m_stCurrent;
282 else // (moving backwards?)
284 int st;
285 for (st = stNew-1; st >= 0; --st)
287 LPWIZARD_STATE pState;
288 if ((pState = FindState (st)) != NULL)
290 m_stCurrent = st;
291 if (!SendStateCommand (st, wcIS_STATE_DISABLED))
292 break;
293 m_stCurrent = stOriginal;
294 SendStateCommand (st, wcSTATE_ENTER);
295 SendStateCommand (st, wcSTATE_LEAVE);
298 stNew = (st >= 0) ? st : m_stCurrent;
302 m_stCurrent = stNew;
304 SendStateCommand (m_stCurrent, wcSTATE_ENTER);
306 if (m_fShowing)
308 Refresh (REFRESH_RIGHT_PANE);
313 BOOL WIZARD::Show (BOOL fShowReq)
315 if (m_fShowing && !fShowReq)
317 m_fShowing = FALSE;
318 if (m_hWnd && IsWindow (m_hWnd))
319 DestroyWindow (m_hWnd);
320 m_hWnd = NULL;
322 else if (!m_fShowing && fShowReq)
324 if (m_iddTemplate == -1)
325 return FALSE;
326 if (m_idcLeftPane == -1)
327 return FALSE;
328 if (m_idcRightPane == -1)
329 return FALSE;
330 if (m_idcBack == -1)
331 return FALSE;
332 if (m_idcNext == -1)
333 return FALSE;
335 if ((m_hWnd = ModelessDialogParam (m_iddTemplate, m_hBkg, (DLGPROC)WIZARD::Template_DlgProc, (LPARAM)this)) == NULL)
336 return FALSE;
337 m_fShowing = TRUE;
339 MSG msg;
340 while (GetMessage (&msg, 0, 0, NULL))
342 if (!IsDialogMessage (m_hWnd, &msg))
344 TranslateMessage (&msg);
345 DispatchMessage (&msg);
348 if (!m_fShowing || !m_hWnd || !IsWindow (m_hWnd))
349 break;
353 return TRUE;
357 void WIZARD::EnableButton (int idcButton, BOOL fEnable)
359 EnableWindow (GetDlgItem (m_hWnd, idcButton), fEnable);
363 void WIZARD::EnableButtons (DWORD dwButtonFlags)
365 EnableWindow (GetDlgItem (m_hWnd, m_idcBack), (dwButtonFlags & BACK_BUTTON) ? TRUE : FALSE);
366 EnableWindow (GetDlgItem (m_hWnd, m_idcNext), (dwButtonFlags & NEXT_BUTTON) ? TRUE : FALSE);
370 void WIZARD::SetButtonText (int idcButton, int idsText)
372 HWND hButton;
373 if ((hButton = GetDlgItem (m_hWnd, idcButton)) != NULL)
375 TCHAR szText[ cchRESOURCE ];
376 GetString (szText, idsText);
377 SetWindowText (hButton, szText);
382 void WIZARD::SetDefaultControl (int idc)
384 HWND hControl;
385 if ((hControl = GetDlgItem (m_hWnd, idc)) == NULL)
387 HWND hRHS;
388 if ((hRHS = GetRightHandWindow()) != NULL)
389 hControl = GetDlgItem (hRHS, idc);
392 if (hControl)
394 PostMessage (m_hWnd, WM_NEXTDLGCTL, (WPARAM)hControl, TRUE);
399 void WIZARD::SetBackground (int iddBackground, BOOL fBlue, DLGPROC dlgproc)
401 m_iddBackground = iddBackground;
402 m_fBlue = fBlue;
403 m_fnBackground = dlgproc;
405 if (m_hBkg && IsWindow (m_hBkg))
407 ShowBackground (FALSE);
408 ShowBackground (TRUE);
413 void WIZARD::SetBackgroundText (int idsText, HFONT hf)
415 GetString (m_szBackground, idsText);
417 if ((hf != NULL) && (hf != m_hfBackground))
419 if (m_hfBackground != NULL)
420 DeleteObject (m_hfBackground);
421 m_hfBackground = hf;
424 if (m_hBkg && IsWindow (m_hBkg))
426 Background_OnSize();
431 void WIZARD::SetBackgroundText (LPTSTR pszText, HFONT hf)
433 if (!pszText)
434 m_szBackground[0] = TEXT('\0');
435 else
436 lstrcpy (m_szBackground, pszText);
438 if ((hf != NULL) && (hf != m_hfBackground))
440 if (m_hfBackground != NULL)
441 DeleteObject (m_hfBackground);
442 m_hfBackground = hf;
445 if (m_hBkg && IsWindow (m_hBkg))
447 Background_OnSize();
452 BOOL WIZARD::ShowBackground (BOOL fShow)
454 if (!fShow && m_hBkg && IsWindow (m_hBkg))
456 DestroyWindow (m_hBkg);
457 m_hBkg = NULL;
459 else if (fShow && !(m_hBkg && IsWindow (m_hBkg)))
461 if ((m_hBkg = ModelessDialogParam (m_iddBackground, NULL, (DLGPROC)WIZARD::Background_DlgProc, (LPARAM)this)) == NULL)
462 return FALSE;
464 RECT rDesktop;
465 SystemParametersInfo (SPI_GETWORKAREA, 0, &rDesktop, 0);
467 WINDOWPLACEMENT wpl;
468 wpl.length = sizeof(wpl);
469 wpl.flags = 0;
470 wpl.showCmd = (GetWindowLong (m_hBkg, GWL_STYLE) & WS_MAXIMIZE) ? SW_SHOWMAXIMIZED : SW_SHOW;
471 wpl.ptMinPosition.x = 0;
472 wpl.ptMinPosition.y = 0;
473 wpl.ptMaxPosition.x = 0;
474 wpl.ptMaxPosition.y = 0;
475 wpl.rcNormalPosition.left = rDesktop.left + cxLEFT_BACKGROUND;
476 wpl.rcNormalPosition.right = rDesktop.right - cxRIGHT_BACKGROUND;
477 wpl.rcNormalPosition.top = rDesktop.top + cyTOP_BACKGROUND;
478 wpl.rcNormalPosition.bottom = rDesktop.bottom - cyBOTTOM_BACKGROUND;
479 SetWindowPlacement (m_hBkg, &wpl);
482 return TRUE;
486 HWND WIZARD::GetBackgroundWindow (void)
488 return m_hBkg;
492 void WIZARD::Refresh (DWORD dwRefFlags)
494 if (dwRefFlags & REFRESH_LEFT_PANE)
496 HWND hLHS;
497 if ((hLHS = GetDlgItem (m_hWnd, m_idcLeftPane)) != NULL)
499 RECT rr;
500 GetClientRect (hLHS, &rr);
501 InvalidateRect (hLHS, &rr, TRUE);
502 UpdateWindow (hLHS);
506 if (dwRefFlags & REFRESH_RIGHT_PANE)
508 HWND hRHS;
509 if ((hRHS = GetDlgItem (m_hWnd, m_idcRightPane)) != NULL)
511 HWND hOld = GetRightHandWindow();
513 LPWIZARD_STATE pState;
514 if ((pState = FindState (m_stCurrent)) != NULL)
516 int stCurrent = m_stCurrent;
518 HWND hNew;
519 if ((hNew = ModelessDialogParam (pState->idd, m_hWnd, pState->dlgproc, pState->lp)) != NULL)
521 if (stCurrent != m_stCurrent)
522 DestroyWindow (hNew);
523 else
525 RECT rRHS;
526 GetRectInParent (hRHS, &rRHS);
527 SetWindowPos (hNew, NULL, rRHS.left, rRHS.top, cxRECT(rRHS), cyRECT(rRHS), SWP_NOZORDER | SWP_NOACTIVATE);
528 SetWindowLong (hNew, GWL_ID, pState->idd);
530 ShowWindow (hNew, SW_SHOW);
531 ShowWindow (hRHS, SW_HIDE);
536 if (hOld != NULL)
537 DestroyWindow (hOld);
543 HWND WIZARD::GetRightHandWindow (void)
545 if (!m_fShowing || !m_hWnd || !IsWindow (m_hWnd))
546 return NULL;
548 HWND hRHS = NULL;
550 for (HWND hFound = ::GetWindow (m_hWnd, GW_CHILD);
551 hFound != NULL;
552 hFound = ::GetWindow (hFound, GW_HWNDNEXT))
554 TCHAR szClassName[ cchRESOURCE ];
555 if (GetClassName (hFound, szClassName, cchRESOURCE))
557 if (!lstrcmp (szClassName, TEXT("#32770"))) // WC_DIALOG
559 if (!hRHS || IsWindowVisible(hRHS))
560 hRHS = hFound;
565 return hRHS;
569 void WIZARD::GeneratePalette (LPRGBQUAD argb)
571 HDC hdc = GetDC (NULL);
572 WORD wDepthDisplay = (WORD)GetDeviceCaps (hdc, BITSPIXEL);
573 ReleaseDC (NULL, hdc);
575 if (wDepthDisplay == 8)
577 BYTE aPalBuffer[ sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY) ];
578 LPLOGPALETTE pPal = (LPLOGPALETTE)aPalBuffer;
579 pPal->palVersion = 0x300;
580 pPal->palNumEntries = 256;
582 size_t ii;
583 for (ii = 0; ii < 256; ++ii)
585 pPal->palPalEntry[ ii ].peRed = (argb) ? argb[ ii ].rgbRed : 0;
586 pPal->palPalEntry[ ii ].peGreen = (argb) ? argb[ ii ].rgbGreen : 0;
587 pPal->palPalEntry[ ii ].peBlue = (argb) ? argb[ ii ].rgbBlue : 0;
588 pPal->palPalEntry[ ii ].peFlags = 0;
591 for (COLORREF clr = clrWASH_DARKEST; clr <= clrWASH_BRIGHTEST; clr += clrWASH_INCREMENT)
593 for (ii = 0; ii < 256; ++ii)
595 if ( (pPal->palPalEntry[ ii ].peRed == GetRValue (clr)) &&
596 (pPal->palPalEntry[ ii ].peGreen == GetGValue (clr)) &&
597 (pPal->palPalEntry[ ii ].peBlue == GetBValue (clr)) )
598 break;
600 if (ii == 256)
602 for (ii = 10; ii < 246; ++ii)
604 if ( (pPal->palPalEntry[ ii ].peRed == 0) &&
605 (pPal->palPalEntry[ ii ].peGreen == 0) &&
606 (pPal->palPalEntry[ ii ].peBlue == 0) )
607 break;
608 if ( (pPal->palPalEntry[ ii ].peRed == 255) &&
609 (pPal->palPalEntry[ ii ].peGreen == 255) &&
610 (pPal->palPalEntry[ ii ].peBlue == 255) )
611 break;
613 if (ii == 246)
614 break;
616 pPal->palPalEntry[ ii ].peRed = GetRValue (clr);
617 pPal->palPalEntry[ ii ].peGreen = GetGValue (clr);
618 pPal->palPalEntry[ ii ].peBlue = GetBValue (clr);
622 m_palGraphic = CreatePalette (pPal);
627 LPWIZARD_STATE WIZARD::FindState (int stFind)
629 for (size_t ii = 0; ii < m_cStates; ++ii)
631 if (m_aStates[ ii ].st == stFind)
632 return &m_aStates[ ii ];
634 return NULL;
638 BOOL WIZARD::SendStateCommand (int st, WIZARD_COMMAND wc)
640 BOOL rc = FALSE;
642 LPWIZARD_STATE pState;
643 if ((pState = FindState (st)) != NULL)
645 rc = (BOOL)CallWindowProc ((WNDPROC)(pState->dlgproc), NULL, WM_COMMAND, MAKEWPARAM(IDC_WIZARD,(WORD)wc), (LPARAM)this);
648 return rc;
652 HRESULT CALLBACK WIZARD::Template_DlgProc (HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
654 if (msg == WM_INITDIALOG)
655 SetWindowLongPtr (hWnd, DWLP_USER, lp);
657 LPWIZARD pWiz = (LPWIZARD)GetWindowLongPtr (hWnd, DWLP_USER);
659 switch (msg)
661 case WM_INITDIALOG:
662 if (pWiz)
663 pWiz->Template_OnInitDialog (hWnd);
664 break;
666 case WM_DESTROY:
667 if (pWiz && (pWiz->m_hWnd == hWnd))
668 pWiz->Show (FALSE);
669 break;
671 case WM_COMMAND:
672 return pWiz->Template_ForwardMessage (hWnd, msg, wp, lp);
675 return FALSE;
679 HRESULT CALLBACK WIZARD::Template_LeftPaneHook (HWND hLHS, UINT msg, WPARAM wp, LPARAM lp)
681 PVOID oldProc = Subclass_FindNextHook (hLHS, WIZARD::Template_LeftPaneHook);
683 switch (msg)
685 case WM_PAINT:
686 LPWIZARD pWiz;
687 if ((pWiz = WIZARD::GetWizard (GetParent (hLHS))) != NULL)
689 if (pWiz->Template_OnPaintLHS (hLHS))
690 return TRUE;
692 break;
694 case WM_DESTROY:
695 Subclass_RemoveHook (hLHS, WIZARD::Template_LeftPaneHook);
696 break;
699 if (oldProc)
700 return (BOOL)CallWindowProc ((WNDPROC)oldProc, hLHS, msg, wp, lp);
701 else
702 return (BOOL)DefWindowProc (hLHS, msg, wp, lp);
706 BOOL WIZARD::Template_ForwardMessage (HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
708 HWND hRHS;
709 if ((hRHS = GetRightHandWindow()) != NULL)
710 return (BOOL)SendMessage (hRHS, msg, wp, lp);
712 LPWIZARD_STATE pState;
713 if ((pState = FindState (m_stCurrent)) != NULL)
714 return (BOOL)CallWindowProc ((WNDPROC)(pState->dlgproc), hWnd, msg, wp, lp);
716 return FALSE;
720 void WIZARD::Template_OnInitDialog (HWND hWnd)
722 m_hWnd = hWnd;
723 m_fShowing = TRUE;
725 HWND hLHS;
726 if ((hLHS = GetDlgItem (m_hWnd, m_idcLeftPane)) != NULL)
728 Subclass_AddHook (hLHS, WIZARD::Template_LeftPaneHook);
731 HWND hRHS;
732 if ((hRHS = GetDlgItem (m_hWnd, m_idcRightPane)) != NULL)
734 ShowWindow (hRHS, SW_HIDE);
737 Refresh (REFRESH_RIGHT_PANE);
739 ShowWindow (m_hWnd, SW_SHOW);
743 BOOL WIZARD::Template_OnPaintLHS (HWND hLHS)
745 BOOL fShow16 = FALSE;
746 BOOL fShow256 = FALSE;
748 HDC hdc = GetDC (NULL);
749 WORD wDepthDisplay = (WORD)GetDeviceCaps (hdc, BITSPIXEL);
750 ReleaseDC (NULL, hdc);
752 if ( (m_bmpGraphic256 != NULL) && (wDepthDisplay >= 8) )
753 fShow256 = TRUE;
754 else if (m_bmpGraphic16 != NULL)
755 fShow16 = TRUE;
756 else
757 return FALSE;
759 PAINTSTRUCT ps;
760 HDC hdcTarget;
761 if ((hdcTarget = BeginPaint (hLHS, &ps)) != NULL)
763 HBITMAP bmpSource = (fShow256) ? m_bmpGraphic256 : m_bmpGraphic16;
765 BITMAP bm;
766 GetObject (bmpSource, sizeof(BITMAP), &bm);
768 RECT rWindow;
769 GetClientRect (hLHS, &rWindow);
771 RECT rSource = { 0, 0, bm.bmWidth, bm.bmHeight };
772 RECT rTarget = rWindow;
774 if (cxRECT(rSource) > cxRECT(rTarget))
776 MoveRect (&rSource, (cxRECT(rSource) - cxRECT(rTarget)) / 2, 0);
777 rSource.right = rSource.left + cxRECT(rTarget);
779 else if (cxRECT(rSource) < cxRECT(rTarget))
781 MoveRect (&rTarget, (cxRECT(rTarget) - cxRECT(rSource)) / 2, 0);
784 if (cyRECT(rSource) > cyRECT(rTarget))
786 MoveRect (&rSource, 0, (cyRECT(rSource) - cyRECT(rTarget)) / 2);
787 rSource.bottom = rSource.top + cyRECT(rTarget);
789 else if (cyRECT(rSource) < cyRECT(rTarget))
791 MoveRect (&rTarget, 0, (cyRECT(rTarget) - cyRECT(rSource)) / 2);
793 rTarget.right = rTarget.left + cxRECT(rSource);
794 rTarget.bottom = rTarget.top + cyRECT(rSource);
796 // If the user has supplied a custom draw-proc, then we should
797 // do our rendering to an off-screen bitmap.
799 HDC hdcFinalTarget = NULL;
800 HBITMAP bmpTempTarget = NULL;
801 if (m_pfnCallback)
803 // First make sure our offscreen buffer is large enough
805 if (!m_bmpBuffer || (cxRECT(m_rBuffer) < cxRECT(rWindow)) || (cyRECT(m_rBuffer) < cyRECT(rWindow)))
807 if (m_bmpBuffer != NULL)
808 DeleteObject (m_bmpBuffer);
809 if ((m_bmpBuffer = CreateCompatibleBitmap (hdcTarget, cxRECT(rWindow), cyRECT(rWindow))) != NULL)
811 m_rBuffer.right = cxRECT(rWindow); // m_rBuffer.left=already 0
812 m_rBuffer.bottom = cyRECT(rWindow); // m_rBuffer.top=already 0
816 // Then set up to double-buffer, if possible
818 if (m_bmpBuffer)
820 hdcFinalTarget = hdcTarget;
821 hdcTarget = CreateCompatibleDC (hdcFinalTarget);
822 bmpTempTarget = (HBITMAP)SelectObject (hdcTarget, m_bmpBuffer);
826 HDC hdcSource = CreateCompatibleDC (hdcTarget);
827 HBITMAP bmpOld = (HBITMAP)SelectObject (hdcSource, bmpSource);
828 HPALETTE palOld = NULL;
829 if ((wDepthDisplay == 8) && (m_palGraphic != NULL) && (fShow256))
831 palOld = SelectPalette (hdcTarget, m_palGraphic, FALSE);
832 RealizePalette (hdcTarget);
835 if ( (bm.bmWidth < cxRECT(rWindow)) || (bm.bmHeight < cyRECT(rWindow)) )
837 COLORREF clrFill = GetPixel (hdcSource, 0, rSource.bottom -1);
838 clrFill = ToPALETTERGB(clrFill);
839 HBRUSH hbrFill = CreateSolidBrush (clrFill);
841 if (bm.bmWidth < cxRECT(rWindow))
843 RECT rr;
844 rr = rWindow;
845 rr.right = rTarget.left;
846 FillRect (hdcTarget, &rr, hbrFill);
848 rr = rWindow;
849 rr.left = rTarget.right;
850 FillRect (hdcTarget, &rr, hbrFill);
853 if (bm.bmHeight < cyRECT(rWindow))
855 RECT rr;
856 rr = rWindow;
857 rr.bottom = rTarget.top;
858 FillRect (hdcTarget, &rr, hbrFill);
860 rr = rWindow;
861 rr.top = rTarget.bottom;
862 FillRect (hdcTarget, &rr, hbrFill);
865 DeleteObject (hbrFill);
868 BitBlt (hdcTarget, rTarget.left, rTarget.top, cxRECT(rTarget), cyRECT(rTarget), hdcSource, rSource.left, rSource.top, SRCCOPY);
870 // Call the user-supplied callback function (if there is one)
872 if (m_pfnCallback)
874 (*m_pfnCallback)(this, hdcTarget, &rWindow, (palOld) ? m_palGraphic : NULL);
877 if (palOld != NULL)
878 SelectPalette (hdcTarget, palOld, FALSE);
880 // If we've been drawing to an off-screen bitmap, blit the result to
881 // the display.
883 if (hdcFinalTarget)
885 BitBlt (hdcFinalTarget, rWindow.left, rWindow.top, cxRECT(rWindow), cyRECT(rWindow), hdcTarget, 0, 0, SRCCOPY);
886 SelectObject (hdcTarget, bmpTempTarget);
887 DeleteDC (hdcTarget);
888 hdcTarget = hdcFinalTarget;
891 SelectObject (hdcSource, bmpOld);
892 DeleteDC (hdcSource);
894 EndPaint (hLHS, &ps);
897 return TRUE;
901 void MoveRect (RECT *_pr, LONG _dx, LONG _dy)
903 _pr->left += _dx;
904 _pr->right += _dx;
905 _pr->top += _dy;
906 _pr->bottom += _dy;
910 void GetRectInParent (HWND hWnd, RECT *pr)
912 POINT pt;
914 GetWindowRect (hWnd, pr);
916 pr->right -= pr->left;
917 pr->bottom -= pr->top; // right/bottom == width/height for now
919 pt.x = pr->left;
920 pt.y = pr->top;
922 ScreenToClient (GetParent (hWnd), &pt);
924 pr->left = pt.x;
925 pr->top = pt.y;
926 pr->right += pr->left;
927 pr->bottom += pr->top;
931 HRESULT CALLBACK WIZARD::Background_DlgProc (HWND hBkg, UINT msg, WPARAM wp, LPARAM lp)
933 if (msg == WM_INITDIALOG)
934 SetWindowLongPtr (hBkg, DWLP_USER, lp);
936 LPWIZARD pWiz = (LPWIZARD)GetWindowLongPtr (hBkg, DWLP_USER);
938 switch (msg)
940 case WM_INITDIALOG:
941 if (pWiz)
942 pWiz->Background_OnInitDialog (hBkg);
943 break;
945 case WM_SIZE:
946 if (pWiz)
947 pWiz->Background_OnSize();
948 break;
950 case WM_DESTROY:
951 if (pWiz)
952 pWiz->Background_OnDestroy();
953 break;
955 case WM_COMMAND:
956 switch (LOWORD(wp))
958 case IDCANCEL:
959 if (pWiz)
960 pWiz->Background_OnClose();
961 else
962 DestroyWindow (hBkg);
963 break;
965 break;
968 if (pWiz && pWiz->m_fnBackground)
970 if (CallWindowProc ((WNDPROC)(pWiz->m_fnBackground), hBkg, msg, wp, lp))
971 return TRUE;
974 return FALSE;
978 HRESULT CALLBACK WIZARD::Background_PaintHook (HWND hBkg, UINT msg, WPARAM wp, LPARAM lp)
980 PVOID oldProc = Subclass_FindNextHook (hBkg, WIZARD::Background_PaintHook);
982 switch (msg)
984 case WM_PAINT:
985 LPWIZARD pWiz;
986 if ((pWiz = WIZARD::GetWizard (hBkg)) != NULL)
988 if (pWiz->Background_OnPaint())
989 return TRUE;
991 break;
993 case WM_DESTROY:
994 Subclass_RemoveHook (hBkg, WIZARD::Background_PaintHook);
995 break;
998 if (oldProc)
999 return CallWindowProc ((WNDPROC)oldProc, hBkg, msg, wp, lp);
1000 else
1001 return DefWindowProc (hBkg, msg, wp, lp);
1006 void WIZARD::Background_OnInitDialog (HWND hBkg)
1008 m_hBkg = hBkg;
1009 Background_OnSize();
1010 Subclass_AddHook (m_hBkg, (DLGPROC)WIZARD::Background_PaintHook);
1014 void WIZARD::Background_OnSize (void)
1016 if (m_bmpBackground)
1018 DeleteObject (m_bmpBackground);
1019 m_bmpBackground = NULL;
1022 RECT rr;
1023 GetClientRect (m_hBkg, &rr);
1025 if (m_fBlue)
1027 HDC hdc = GetDC (NULL);
1028 WORD wDepthDisplay = (WORD)GetDeviceCaps (hdc, BITSPIXEL);
1029 ReleaseDC (NULL, hdc);
1031 hdc = GetDC (m_hBkg);
1032 HDC hdcTarget = CreateCompatibleDC (hdc);
1034 if ((m_bmpBackground = CreateCompatibleBitmap (hdc, cxRECT(rr), cyRECT(rr))) != NULL)
1036 HBITMAP bmpOld = (HBITMAP)SelectObject (hdcTarget, m_bmpBackground);
1038 HPALETTE palOld = NULL;
1039 if (m_palGraphic)
1041 palOld = SelectPalette (hdcTarget, m_palGraphic, FALSE);
1042 RealizePalette (hdcTarget);
1045 size_t yy = 0;
1046 size_t cy = cyRECT(rr) / ((clrWASH_BRIGHTEST - clrWASH_DARKEST) / clrWASH_INCREMENT);
1047 for (COLORREF clr = clrWASH_BRIGHTEST; clr >= clrWASH_DARKEST; clr -= clrWASH_INCREMENT)
1049 RECT rSection = rr;
1050 rSection.top = (LONG)yy;
1051 rSection.bottom = (LONG)(yy +cy);
1052 HBRUSH hbr = CreateSolidBrush (ToPALETTERGB(clr));
1053 FillRect (hdcTarget, &rSection, hbr);
1054 DeleteObject (hbr);
1055 yy += cy;
1058 if (m_szBackground[0] != TEXT('\0'))
1060 HFONT hfOld = (HFONT)SelectObject (hdcTarget, m_hfBackground);
1061 COLORREF clrOld = SetTextColor (hdcTarget, clrWASH_TEXT_BG);
1062 SetBkMode (hdcTarget, TRANSPARENT);
1064 RECT rText = rr;
1065 rText.left += xTEXT + cxSHADOW;
1066 rText.top += yTEXT + cySHADOW;
1067 DrawTextEx (hdcTarget, m_szBackground, lstrlen(m_szBackground), &rText, DT_NOPREFIX | DT_LEFT, NULL);
1069 rText.left -= cxSHADOW;
1070 rText.top -= cySHADOW;
1071 SetTextColor (hdcTarget, clrWASH_TEXT_FG);
1072 DrawTextEx (hdcTarget, m_szBackground, lstrlen(m_szBackground), &rText, DT_NOPREFIX | DT_LEFT, NULL);
1074 SetTextColor (hdcTarget, clrOld);
1075 SelectObject (hdcTarget, hfOld);
1078 if (palOld)
1079 SelectPalette (hdcTarget, palOld, FALSE);
1081 SelectObject (hdcTarget, bmpOld);
1084 DeleteDC (hdcTarget);
1085 ReleaseDC (m_hBkg, hdc);
1088 InvalidateRect (m_hBkg, &rr, TRUE);
1089 UpdateWindow (m_hBkg);
1093 void WIZARD::Background_OnDestroy (void)
1095 if (m_bmpBackground)
1097 DeleteObject (m_bmpBackground);
1098 m_bmpBackground = NULL;
1103 void WIZARD::Background_OnClose (void)
1105 LPWIZARD_STATE pState;
1107 if (m_hWnd && IsWindow (m_hWnd))
1109 PostMessage (m_hWnd, WM_COMMAND, MAKEWPARAM(IDCANCEL,BN_CLICKED), (LPARAM)GetDlgItem(m_hWnd,IDCANCEL));
1111 else if ((pState = FindState (m_stCurrent)) != NULL)
1113 CallWindowProc ((WNDPROC)(pState->dlgproc), m_hBkg, WM_COMMAND, MAKEWPARAM(IDCANCEL,BN_CLICKED), 0);
1115 else
1117 ShowBackground (FALSE);
1122 BOOL WIZARD::Background_OnPaint (void)
1124 if (!m_bmpBackground)
1125 return FALSE;
1127 PAINTSTRUCT ps;
1128 HDC hdcTarget;
1129 if ((hdcTarget = BeginPaint (m_hBkg, &ps)) != NULL)
1131 BITMAP bm;
1132 GetObject (m_bmpBackground, sizeof(BITMAP), &bm);
1134 HDC hdcSource = CreateCompatibleDC (hdcTarget);
1135 HBITMAP bmpOld = (HBITMAP)SelectObject (hdcSource, m_bmpBackground);
1136 HPALETTE palOld = NULL;
1137 if (m_palGraphic)
1139 palOld = SelectPalette (hdcSource, m_palGraphic, FALSE);
1140 RealizePalette (hdcTarget);
1143 BitBlt (hdcTarget, 0, 0, bm.bmWidth, bm.bmHeight, hdcSource, 0, 0, SRCCOPY);
1145 if (palOld != NULL)
1146 SelectPalette (hdcTarget, palOld, FALSE);
1147 SelectObject (hdcSource, bmpOld);
1148 DeleteDC (hdcSource);
1150 EndPaint (m_hBkg, &ps);
1153 return TRUE;