windows-nt/Source/XPSP1/NT/shell/applets/upgrade/dlgapp.cpp

1528 lines
44 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
//////////////////////////////////////////////////////////////////////////
//
// dlgapp.cpp
//
// This file contains the main entry point into the application and
// the implementation of the CDlgApp class.
//
// (C) Copyright 1997 by Microsoft Corporation. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <commctrl.h>
#include <shlwapi.h> // for string compare functions
#include <debug.h>
#include <tchar.h>
#include <winuser.h>
#pragma hdrstop
#include "dlgapp.h"
#include "util.h"
#include "resource.h"
WNDPROC g_fnBtnProc; // the window proc for a button.
#define LAUNCHTIMER 101
#define WAITTIMER 102
#define TEXT_TITLE 0
#define TEXT_HEADER 1
#define TEXT_BODY 2
#define TEXT_SUB 3
#define BUTTONTEXTGAP 5
#define TRANSBUTTONGAP 10
DWORD rgdwText[7][4] = {{IDS_TEXT0_TITLE, IDS_TEXT0_HEADER, IDS_TEXT0, IDS_TEXT0_SUB},
{IDS_TEXT1_TITLE, IDS_TEXT1_HEADER, IDS_TEXT1, IDS_TEXT1_SUB},
{IDS_TEXT2_TITLE, IDS_TEXT2_HEADER, IDS_TEXT2, IDS_TEXT2_SUB},
{IDS_TEXT3_TITLE, IDS_TEXT3_HEADER, IDS_TEXT3, IDS_TEXT3_SUB},
{IDS_TEXT4_TITLE, IDS_TEXT4_HEADER, IDS_TEXT4, IDS_TEXT4_SUB},
{IDS_TEXT5_TITLE, IDS_TEXT5_HEADER, IDS_TEXT5, IDS_TEXT5_SUB},
{IDS_TEXT6_TITLE, IDS_TEXT6_HEADER, IDS_TEXT6, IDS_TEXT6_SUB}};
RECT rgrectText[4] = {{97, 18, 797, 98}, {120, 100, 750, 200}, {120, 200, 750, 450}, {120, 430, 750, 520}};
RECT rgrectText640[4] = {{77, 28, 597, 98}, {50, 90, 620, 150}, {50, 160, 620, 350}, {50, 330, 620, 400}};
DWORD rgdwLabel[] = {IDS_MENULABEL0, IDS_MENULABEL1, IDS_MENULABEL2, IDS_MENULABEL3, IDS_MENULABEL4, IDS_MENULABEL5, IDS_MENULABEL6}; // which text label for a menu item
DWORD rgdwPosition[] = {4, 2, 3, 4, 0, 0, 1};
#define EXIT_DEX 0
#define BACK_DEX 1
#define NEXT_DEX 2
#define FINISH_DEX 3
#define LINK_DEX 4
#define RADIO_1_DEX 5
#define RADIO_0_DEX 6
#define EMPTY 99
POINT rgPtIcons[] = {{150,320}, {150, 360}, {0, 537}, {0, 537}, {740, 537}};
POINT rgPtIconText[] = {{180,320}, {180, 360}, {0, 537}, {0, 537}, {0, 537}};
UINT cWidthIconText[] = {0, 0, 0, 0, 0};
POINT rgPtIcons640[] = {{80,250}, {80, 280}, {0, 403}, {0, 403}, {600, 403}};
POINT rgPtIconText640[] = {{110,250}, {110, 280}, {0, 403}, {0, 403}, {600, 403}};
DWORD rgdwMenu[7][5] = {{EXIT_DEX},
{EXIT_DEX, NEXT_DEX},
{EXIT_DEX, BACK_DEX, NEXT_DEX, RADIO_1_DEX, RADIO_0_DEX},
{EXIT_DEX, BACK_DEX, NEXT_DEX},
{EXIT_DEX, BACK_DEX, NEXT_DEX},
{FINISH_DEX, BACK_DEX, LINK_DEX},
{EXIT_DEX}};
DWORD rgdwMenuByPos[7][5] = {{EMPTY, EMPTY, EMPTY, EMPTY, EXIT_DEX},
{EMPTY, EMPTY, EMPTY, NEXT_DEX, EXIT_DEX},
{RADIO_1_DEX, RADIO_0_DEX, BACK_DEX, NEXT_DEX, EXIT_DEX},
{EMPTY, EMPTY, BACK_DEX, NEXT_DEX, EXIT_DEX},
{EMPTY, EMPTY, BACK_DEX, NEXT_DEX, EXIT_DEX},
{LINK_DEX, EMPTY, BACK_DEX, EMPTY, FINISH_DEX},
{EMPTY, EMPTY, EMPTY, EMPTY, EXIT_DEX}};
UINT rgcMenu[] = {1, 2, 5, 3, 3, 3, 1};
//////////////////////////////////////////////////////////////////////////
// #defines
//////////////////////////////////////////////////////////////////////////
#define FLAG_HEIGHT 40
#define FLAG_WIDTH 45
#define MENUICON_HEIGHT 24
#define MENUICON_WIDTH 24
//////////////////////////////////////////////////////////////////////////
// Code
//////////////////////////////////////////////////////////////////////////
typedef DWORD (WINAPI *PFNGETLAYOUT)(HDC); // gdi32!GetLayout
typedef DWORD (WINAPI *PFNSETLAYOUT)(HDC, DWORD); // gdi32!SetLayout
/**
* This method is our contstructor for our class. It initialize all
* of the instance data.
*/
CDlgApp::CDlgApp()
{
g_fnBtnProc = NULL;
m_hInstance = NULL;
m_hwnd = NULL;
m_fHighContrast = FALSE;
m_fDynamicUpdate = TRUE;
m_hfontTitle = NULL;
m_hfontHeader = NULL;
m_hfontMenu = NULL;
m_hfontText = NULL;
m_hbrPanel = NULL;
m_hbrCenter = NULL;
// store desktop width
RECT rcDesktop;
SystemParametersInfo(SPI_GETWORKAREA,0, &rcDesktop, FALSE);
m_cDesktopWidth = rcDesktop.right - rcDesktop.left;
m_cDesktopHeight = rcDesktop.bottom - rcDesktop.top;
if (m_cDesktopWidth > 800)
{
m_f8by6 = TRUE;
}
else
{
m_f8by6 = FALSE;
}
m_hdcFlag = NULL;
m_hdcFlagRTL = NULL;
m_hdcGradientTop = NULL;
m_hdcGradientTop256 = NULL;
m_hdcGradientBottom = NULL;
m_hdcGradientBottom256 = NULL;
for (int i = 0; i < ARRAYSIZE(m_rghdcArrows); i++)
{
for (int j = 0; j < ARRAYSIZE(m_rghdcArrows[0]); j++)
{
for (int k = 0; k < ARRAYSIZE(m_rghdcArrows[0][0]); k++)
{
m_rghdcArrows[i][j][k] = NULL;
}
}
}
m_hcurHand = NULL;
if (!IsCheckableOS())
{
m_dwScreen = 0; // machine cannot be checked
m_iSelectedItem = EXIT_DEX;
}
else if (IsUserRestricted())
{
m_dwScreen = 6; // user does not have needed permissions to check machine
m_iSelectedItem = EXIT_DEX;
}
else
{
m_dwScreen = 1; // first real page
m_iSelectedItem = NEXT_DEX;
}
m_fLowColor = FALSE;
m_iColors = -1;
m_hpal = NULL;
}
CDlgApp::~CDlgApp()
{
DeleteObject(m_hfontTitle);
DeleteObject(m_hfontHeader);
DeleteObject(m_hfontMenu);
DeleteObject(m_hfontText);
DeleteObject(m_hbrPanel);
DeleteObject(m_hbrCenter);
DeleteDC(m_hdcFlag);
DeleteDC(m_hdcFlagRTL);
DeleteDC(m_hdcGradientTop);
DeleteDC(m_hdcGradientTop256);
DeleteDC(m_hdcGradientBottom);
DeleteDC(m_hdcGradientBottom256);
for (int i = 0; i < ARRAYSIZE(m_rghdcArrows); i++)
{
for (int j = 0; j < ARRAYSIZE(m_rghdcArrows[0]); j++)
{
for (int k = 0; k < ARRAYSIZE(m_rghdcArrows[0][0]); k++)
{
DeleteDC(m_rghdcArrows[i][j][k]);
}
}
}
}
/**
* This method will register our window class for the application.
*
* @param hInstance The application instance handle.
*
* @return No return value.
*/
void CDlgApp::Register(HINSTANCE hInstance)
{
WNDCLASS wndclass;
m_hInstance = hInstance;
wndclass.style = CS_OWNDC | CS_DBLCLKS;
wndclass.lpfnWndProc = s_WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WEBAPP));
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = WINDOW_CLASS;
RegisterClass(&wndclass);
}
/**
* This method will initialize the data object.
*
* @return No return value.
*/
BOOL CDlgApp::InitializeData(LPSTR pszCommandLine)
{
// Determine if we should use Direct Animaiton to display our intro graphics.
// We don't use DA on slow machines, machines with less than 256 color displays,
// and hydra terminals. For everything else we use DA.
HWND hwnd = GetDesktopWindow();
HDC hdc = GetDC( hwnd );
m_iColors = GetDeviceCaps( hdc, NUMCOLORS );
m_fLowColor = ((m_iColors != -1) && (m_iColors <= 256));
if ( m_fLowColor )
{
m_hpal = CreateHalftonePalette(hdc);
}
// Are we in accesibility mode? This call won't work on NT 4.0 because this flag wasn't known.
HIGHCONTRAST hc;
hc.cbSize = sizeof(HIGHCONTRAST);
hc.dwFlags = 0; // avoid random result should SPI fail
if ( SystemParametersInfo( SPI_GETHIGHCONTRAST, sizeof(HIGHCONTRAST), &hc, 0 ) )
{
m_fHighContrast = ( hc.dwFlags & HCF_HIGHCONTRASTON );
}
else
{
// we must be on NT 4.0 or below. Just assume we aren't in high contrast mode.
ASSERT( FALSE == m_fHighContrast );
}
// 210679: go to HighContrast mode if we're in 16-color mode as well
if ( m_fLowColor && (m_iColors <= 16))
{
m_fHighContrast = TRUE;
}
// Set the color table based on our HighContrast mode setting.
_SetColorTable();
// create the fonts that we need to use.
_CreateFonts(hdc);
// create the images
_CreateBitmaps();
_CreateArrowBitmaps();
_CreateGradientBitmaps();
m_hcurHand = LoadCursor( m_hInstance, MAKEINTRESOURCE(IDC_BRHAND) );
ReleaseDC(hwnd, hdc);
return TRUE;
}
#define CENTER_RGB_VALUES RGB(90,126,220)
#define PANEL_RGB_VALUES RGB(0,51,152)
#define TITLE_RGB_VALUES RGB(255, 255, 255)
#define HEADER_RGB_VALUES RGB(214, 223, 245)
#define SHADOW_RGB_VALUES RGB(52, 98, 189)
#define TEXT_RGB_VALUES RGB(255, 255, 255)
#define DISABLED_RGB_VALUES RGB(128, 128, 128)
BOOL CDlgApp::_SetColorTable()
{
if ( m_fHighContrast )
{
// set to high contrast values
m_hbrPanel = (HBRUSH)(COLOR_BTNFACE+1);
m_hbrCenter = (HBRUSH)(COLOR_WINDOW+1);
m_crNormalText = GetSysColor(COLOR_WINDOWTEXT);
m_crTitleText = m_crNormalText;
m_crHeaderText = m_crNormalText;
m_crCenterPanel = GetSysColor(COLOR_WINDOW);
m_crBottomPanel = GetSysColor(COLOR_WINDOW);
}
else
{
m_crTitleText = TITLE_RGB_VALUES;
m_crHeaderText = HEADER_RGB_VALUES;
m_crShadow = SHADOW_RGB_VALUES;
m_crNormalText = TEXT_RGB_VALUES;
m_crCenterPanel = CENTER_RGB_VALUES;
m_crBottomPanel = PANEL_RGB_VALUES;
if ( !m_fLowColor )
{
m_hbrPanel = CreateSolidBrush( PANEL_RGB_VALUES );
m_hbrCenter = CreateSolidBrush( CENTER_RGB_VALUES );
}
else
{
HBITMAP hbmp;
hbmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_PANEL), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
if (hbmp)
{
m_hbrPanel = CreatePatternBrush(hbmp);
DeleteObject(hbmp);
}
else
{
m_hbrPanel = (HBRUSH)(COLOR_BTNFACE+1);
}
hbmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_CENTER), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
if (hbmp)
{
m_hbrCenter = CreatePatternBrush(hbmp);
DeleteObject(hbmp);
}
else
{
m_hbrCenter = (HBRUSH)(COLOR_WINDOW+1);
}
}
}
return TRUE;
}
// this is called once for each font that matches the fonts we care about
int CALLBACK FoundFont
(
ENUMLOGFONTEX *lpelfe, // logical-font data
NEWTEXTMETRICEX *lpntme, // physical-font data
DWORD FontType, // type of font
LPARAM lParam // application-defined data
)
{
*((BOOL*)lParam) = TRUE;
return 0;
}
BOOL CDlgApp::_CreateFonts(HDC hdc)
{
#define RGFONTDEX_LARGE 0
#define RGFONTDEX_SMALL 1
#define RGFONTDEX_TITLE 0
#define RGFONTDEX_HEADER 1
#define RGFONTDEX_MENU 2
#define RGFONTDEX_FULL 0
#define RGFONTDEX_BACKUP 1
// [in] array of IDs, arranged by {title, header, menu} x { nice font, backup font}
const int rgFontID[4][2] =
{{IDS_FONTFACE_TITLE, IDS_FONTFACE_TITLE_BACKUP},
{IDS_FONTFACE_HEADER,IDS_FONTFACE_HEADER_BACKUP},
{IDS_FONTFACE_MENU, IDS_FONTFACE_MENU_BACKUP},
{IDS_FONTFACE_TEXT, IDS_FONTFACE_TEXT_BACKUP}};
// [in] array of heights, arranged by {large x small} x {title, header, menu} x { nice font, backup font}
const int rgFontHeight[2][4][2] =
{{{IDS_FONTCY_TITLE, IDS_FONTCY_TITLE_BACKUP},
{IDS_FONTCY_HEADER, IDS_FONTCY_HEADER_BACKUP},
{IDS_FONTCY_MENU, IDS_FONTCY_MENU_BACKUP},
{IDS_FONTCY_TEXT, IDS_FONTCY_TEXT_BACKUP}},
{{IDS_FONTCY_TITLE_LIL, IDS_FONTCY_TITLE_BACKUP_LIL},
{IDS_FONTCY_HEADER_LIL, IDS_FONTCY_HEADER_BACKUP_LIL},
{IDS_FONTCY_MENU_LIL, IDS_FONTCY_MENU_BACKUP_LIL},
{IDS_FONTCY_TEXT_LIL, IDS_FONTCY_TEXT_BACKUP_LIL}}};
// [out] array of pointers to the fonts
HFONT* rgpFont[4] = {&m_hfontTitle, &m_hfontHeader, &m_hfontMenu, &m_hfontText};
// [out] array of pointers heights of each font
int* rgpcyFont[4] = {&m_cTitleFontHeight, &m_cHeaderFontHeight, &m_cMenuFontHeight, &m_cTextFontHeight};
LOGFONT lf;
CHARSETINFO csInfo;
TCHAR szFontSize[6];
for (int i = 0; i < ARRAYSIZE(rgpFont); i++)
{
memset(&lf,0,sizeof(lf));
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfPitchAndFamily = DEFAULT_PITCH|FF_SWISS;
LoadStringAuto( m_hInstance, rgFontID[i][RGFONTDEX_FULL], lf.lfFaceName, ARRAYSIZE(lf.lfFaceName) );
// Set charset
if (TranslateCharsetInfo((DWORD*)IntToPtr(GetACP()), &csInfo, TCI_SRCCODEPAGE) == 0)
{
csInfo.ciCharset = 0;
}
lf.lfCharSet = (BYTE)csInfo.ciCharset;
// TODO: If user has accesibility large fonts turned on then scale the font sizes.
LoadStringAuto( m_hInstance, rgFontHeight[m_f8by6 ? 0 : 1][i][RGFONTDEX_FULL], szFontSize, ARRAYSIZE(szFontSize) );
*(rgpcyFont[i]) = MulDiv((_ttoi(szFontSize)), GetDeviceCaps(hdc, LOGPIXELSY), 72);
lf.lfHeight = -(*(rgpcyFont[i]));
BOOL fFound = FALSE;
EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)FoundFont, (LPARAM)&fFound, 0);
if (!fFound)
{
LoadStringAuto( m_hInstance, rgFontID[i][RGFONTDEX_BACKUP], lf.lfFaceName, ARRAYSIZE(lf.lfFaceName) );
LoadStringAuto( m_hInstance, rgFontHeight[m_f8by6 ? 0 : 1][i][RGFONTDEX_BACKUP], szFontSize, ARRAYSIZE(szFontSize) );
*(rgpcyFont[i]) = MulDiv((_ttoi(szFontSize)), GetDeviceCaps(hdc, LOGPIXELSY), 72);
lf.lfHeight = -(*(rgpcyFont[i]));
}
*(rgpFont[i]) = CreateFontIndirect(&lf);
}
return TRUE;
}
#define BITMAPTYPE_NORMAL 0x0
#define BITMAPTYPE_LOWCOLOR 0x1
BOOL CDlgApp::_CreateBitmaps()
{
const int rgiBitmapID[2][2] = {{IDB_FLAG, IDB_FLAG_256}, {IDB_FLAG_RTL, IDB_FLAG_RTL_256}}; // [in]
HDC* rgphdc[2] = {&m_hdcFlag, &m_hdcFlagRTL}; // [out]
int iBitmapType = (m_fLowColor) ? BITMAPTYPE_LOWCOLOR : BITMAPTYPE_NORMAL;
for (int i = 0; i < ARRAYSIZE(rgphdc); i++)
{
HBITMAP hbm;
BITMAP bm;
*(rgphdc[i]) = CreateCompatibleDC(NULL);
hbm = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(rgiBitmapID[i][iBitmapType]), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
GetObject(hbm,sizeof(bm),&bm);
SelectObject( *(rgphdc[i]), hbm );
}
return TRUE;
}
BOOL CDlgApp::_CreateArrowBitmaps()
{
const int rgiBitmapID[2][6][2] =
{{{IDB_BACK, IDB_BACK_HOVER},
{IDB_NEXT, IDB_NEXT_HOVER},
{IDB_CLOSE, IDB_CLOSE_HOVER},
{IDB_CANCEL, IDB_CANCEL_HOVER},
{IDB_RADIO_ON, IDB_RADIO_ON_HOVER},
{IDB_RADIO_OFF, IDB_RADIO_OFF_HOVER}},
{{IDB_BACK_256, IDB_BACK_HOVER_256},
{IDB_NEXT_256, IDB_NEXT_HOVER_256},
{IDB_CLOSE_256, IDB_CLOSE_HOVER_256},
{IDB_CANCEL_256, IDB_CANCEL_HOVER_256},
{IDB_RADIO_ON_256, IDB_RADIO_ON_HOVER_256},
{IDB_RADIO_OFF_256, IDB_RADIO_OFF_HOVER_256}}}; // [in]
for (int i = 0; i < ARRAYSIZE(m_rghdcArrows); i++)
{
for (int j = 0; j < ARRAYSIZE(m_rghdcArrows[0]); j++)
{
for (int k = 0; k < ARRAYSIZE(m_rghdcArrows[0][0]); k++)
{
HBITMAP hbm;
BITMAP bm;
m_rghdcArrows[i][j][k] = CreateCompatibleDC(NULL);
hbm = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(rgiBitmapID[i][j][k]), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
GetObject(hbm,sizeof(bm),&bm);
SelectObject( m_rghdcArrows[i][j][k], hbm );
}
}
}
return TRUE;
}
BOOL CDlgApp::_CreateGradientBitmaps()
{
const int rgiBitmapID[4] = {IDB_GRADIENT_TOP, IDB_GRADIENT_TOP_256, IDB_GRADIENT_BOTTOM, IDB_GRADIENT_BOTTOM_256}; // [in]
HDC* rgphdc[4] = {&m_hdcGradientTop, &m_hdcGradientTop256, &m_hdcGradientBottom, &m_hdcGradientBottom256}; // [out]
for (int i = 0; i < ARRAYSIZE(rgphdc); i++)
{
HBITMAP hbm;
BITMAP bm;
*(rgphdc[i]) = CreateCompatibleDC(NULL);
hbm = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(rgiBitmapID[i]), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
GetObject(hbm,sizeof(bm),&bm);
SelectObject( *(rgphdc[i]), hbm );
}
return TRUE;
}
UINT CDlgApp::_StringWidth(HDC hdc, UINT idString, INT iLogPixelSx)
{
TCHAR szBuffer[256];
SIZE size;
LoadString(m_hInstance, idString, szBuffer, ARRAYSIZE(szBuffer));
GetTextExtentPoint32(hdc, szBuffer, lstrlen(szBuffer), &size);
return (size.cx * iLogPixelSx) / 80;
}
UINT CDlgApp::_StringHeight(HDC hdc, UINT idString, INT iLogPixelSy)
{
TCHAR szBuffer[256];
SIZE size;
LoadString(m_hInstance, idString, szBuffer, ARRAYSIZE(szBuffer));
GetTextExtentPoint32(hdc, szBuffer, lstrlen(szBuffer), &size);
return (size.cy * iLogPixelSy) / 80;
}
BOOL CDlgApp::_AdjustIconPlacement()
{
HDC hdc = GetDC(m_hwnd);
UINT cx;
if (hdc)
{
UINT i;
INT iLogPixelSx = GetDeviceCaps(hdc, LOGPIXELSX);
cWidthIconText[0] = m_f8by6 ? 250 : 200;
cWidthIconText[1] = m_f8by6 ? 250 : 200;
cWidthIconText[2] = _StringWidth(hdc, IDS_MENULABEL1, iLogPixelSx); // BACK
cWidthIconText[3] = _StringWidth(hdc, IDS_MENULABEL2, iLogPixelSx); // NEXT
// iterate over CANCEL, FINISH
cWidthIconText[4] = 0;
for (i = IDS_MENULABEL0; i <= IDS_MENULABEL3; i += 3)
{
cx = _StringWidth(hdc, i, iLogPixelSx);
if (cx > cWidthIconText[4])
{
cWidthIconText[4] = cx;
}
}
ReleaseDC(m_hwnd, hdc);
cx = cWidthIconText[4];
rgPtIconText[4].x = rgPtIcons[4].x - cx - BUTTONTEXTGAP; // cancel/finish text
rgPtIconText640[4].x = rgPtIcons640[4].x - cx - BUTTONTEXTGAP; // cancel/finish text
rgPtIcons[3].x = rgPtIconText[4].x - MENUICON_WIDTH - TRANSBUTTONGAP; // next button
rgPtIcons640[3].x = rgPtIconText640[4].x - MENUICON_WIDTH - TRANSBUTTONGAP; // next button
cx = _StringWidth(hdc, IDS_MENULABEL2, iLogPixelSx);
rgPtIconText[3].x = rgPtIcons[3].x - cx - BUTTONTEXTGAP; // next text
rgPtIconText640[3].x = rgPtIcons640[3].x - cx - BUTTONTEXTGAP; // next text
rgPtIcons[2].x = rgPtIconText[3].x - MENUICON_WIDTH - TRANSBUTTONGAP; // back button
rgPtIcons640[2].x = rgPtIconText640[3].x - MENUICON_WIDTH - TRANSBUTTONGAP; // back button
cx = _StringWidth(hdc, IDS_MENULABEL1, iLogPixelSx);
rgPtIconText[2].x = rgPtIcons[2].x - cx - BUTTONTEXTGAP; // back text
rgPtIconText640[2].x = rgPtIcons640[2].x - cx - BUTTONTEXTGAP; // back text
}
return TRUE;
}
BOOL CDlgApp::_AdjustToFitFonts()
{
HDC hdc = GetDC(m_hwnd);
if (hdc)
{
SetMapMode(hdc,MM_TEXT);
INT iLogPixelSy = GetDeviceCaps(hdc, LOGPIXELSY);
for (UINT i = 0; i < ARRAYSIZE(rgPtIcons); i++ )
{
UINT dex = rgdwMenuByPos[m_dwScreen][i];
if (EMPTY != dex)
{
POINT pt = *((m_f8by6) ? &rgPtIconText[i] : &rgPtIconText640[i]);
HWND hwnd = GetDlgItem(m_hwnd, IDM_MENUITEM0+i);
SetWindowPos(hwnd, NULL, pt.x, pt.y, cWidthIconText[i], (3 * _StringHeight(hdc, rgdwLabel[dex], iLogPixelSy)) / 2, SWP_NOZORDER );
}
}
ReleaseDC(m_hwnd, hdc);
}
return TRUE;
}
#define BITMAPSTUFF(rgarrows) {phdcBitmap = (m_iSelectedItem == rgdwMenuByPos[m_dwScreen][i]) ? &(rgarrows[1]) : &(rgarrows[0]); }
BOOL CDlgApp::_DrawMenuIcons(BOOL fEraseBackground)
{
RECT rect;
UINT i;
HDC hdc = GetDC(m_hwnd);
if (hdc)
{
HPALETTE hpalOld = NULL;
if ( m_hpal )
{
hpalOld = SelectPalette(hdc, m_hpal, FALSE);
RealizePalette(hdc);
}
HDC* phdcBitmap;
for (i=0; i < ARRAYSIZE(rgPtIcons); i++ )
{
switch (rgdwMenuByPos[m_dwScreen][i])
{
case EMPTY:
continue;
case BACK_DEX:
BITMAPSTUFF(m_rghdcArrows[m_fLowColor ? 1 : 0][0]);
break;
case NEXT_DEX:
case LINK_DEX:
BITMAPSTUFF(m_rghdcArrows[m_fLowColor ? 1 : 0][1]);
break;
case FINISH_DEX:
BITMAPSTUFF(m_rghdcArrows[m_fLowColor ? 1 : 0][2]);
break;
case EXIT_DEX:
BITMAPSTUFF(m_rghdcArrows[m_fLowColor ? 1 : 0][3]);
break;
case RADIO_1_DEX:
BITMAPSTUFF(m_rghdcArrows[m_fLowColor ? 1 : 0][m_fDynamicUpdate ? 4 : 5]);
break;
case RADIO_0_DEX:
BITMAPSTUFF(m_rghdcArrows[m_fLowColor ? 1 : 0][m_fDynamicUpdate ? 5 : 4]);
break;
}
rect.left = m_f8by6 ? rgPtIcons[i].x : rgPtIcons640[i].x;
rect.top = m_f8by6 ? rgPtIcons[i].y : rgPtIcons640[i].y;
rect.right = rect.left + MENUICON_WIDTH; // arrow width
rect.bottom = rect.top + MENUICON_HEIGHT; // arrow height as well
BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, *phdcBitmap, 0,0, SRCCOPY );
}
if(hpalOld)
SelectPalette(hdc, hpalOld, FALSE);
ReleaseDC(m_hwnd, hdc);
}
return TRUE;
}
void CDlgApp::_InvalidateRectIntl(HWND hwnd, RECT* pRect, BOOL fBackgroundClear)
{
RECT* pRectToUse = pRect; // default to normal case (don't flip)
RECT rectRTL;
if (pRect)
{
OSVERSIONINFO osvi;
if (GetVersionEx(&osvi) &&
(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
Mirror_IsWindowMirroredRTL(hwnd)) // right to left on Win9X
{
rectRTL.top = pRect->top;
rectRTL.bottom = pRect->bottom;
rectRTL.right = m_cxClient - pRect->left;
rectRTL.left = m_cxClient - pRect->right;
pRectToUse = &rectRTL;
}
}
InvalidateRect(hwnd, pRectToUse, fBackgroundClear);
}
/**
* This method will create the application window.
*
* @return No return value.
*/
void CDlgApp::Create(int nCmdShow)
{
//
// load the window title from the resource.
//
TCHAR szTitle[MAX_PATH];
LoadStringAuto(m_hInstance, IDS_TITLEBAR, szTitle, MAX_PATH);
DWORD dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
if (m_f8by6)
{
m_cxClient = 800;
m_cyClient = 600;
}
else
{
m_cxClient = 640;
m_cyClient = 460;
}
m_hwnd = CreateWindowEx(
WS_EX_CONTROLPARENT,
WINDOW_CLASS,
szTitle,
dwStyle,
0,
0,
m_cxClient,
m_cyClient,
NULL,
NULL,
m_hInstance,
this);
// set the client area to a fixed size and center the window on screen
RECT rect = {0};
rect.left = (m_cDesktopWidth - m_cxClient) / 2;
rect.top = (m_cDesktopHeight - m_cyClient) / 2;
rect.right = m_cDesktopWidth - rect.left;
rect.bottom = m_cDesktopHeight - rect.top;
AdjustWindowRect( &rect, dwStyle, FALSE );
SetWindowPos(m_hwnd, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
ShowWindow(m_hwnd, SW_SHOW);
m_cxTopPanel = m_f8by6 ? 80 : 84;
m_cyBottomPanel = m_f8by6 ? 501 : 391;
_InvalidateRectIntl(m_hwnd, NULL, TRUE);
}
/**
* This method is our application message loop.
*
* @return No return value.
*/
void CDlgApp::MessageLoop()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
// IsDialogMessage cannot understand the concept of ownerdraw default pushbuttons. It treats
// these attributes as mutually exclusive. As a result, we handle this ourselves. We want
// whatever control has focus to act as the default pushbutton.
if ( (WM_KEYDOWN == msg.message) && (VK_RETURN == msg.wParam) )
{
HWND hwndFocus = GetFocus();
if ( hwndFocus )
{
SendMessage(m_hwnd, WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndFocus), BN_CLICKED), (LPARAM)hwndFocus);
}
continue;
}
if ( IsDialogMessage(m_hwnd, &msg) )
continue;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
/**
* This is the window procedure for the container application. It is used
* to deal with all messages to our window.
*
* @param hwnd Window handle.
* @param msg The window message.
* @param wParam Window Parameter.
* @param lParam Window Parameter.
*
* @return LRESULT
*/
LRESULT CALLBACK CDlgApp::s_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
CDlgApp *pThis = (CDlgApp *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
switch(msg)
{
case WM_NCCREATE:
{
CDlgApp* pThisCreate = (CDlgApp *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LRESULT)pThisCreate);
}
break;
case WM_CREATE:
return pThis->OnCreate(hwnd);
case WM_DESTROY:
return pThis->OnDestroy();
case WM_ACTIVATE:
return pThis->OnActivate(wParam);
case WM_PAINT:
return pThis->OnPaint((HDC)wParam);
case WM_ERASEBKGND:
return pThis->OnEraseBkgnd((HDC)wParam);
case WM_LBUTTONUP:
return pThis->OnLButtonUp(LOWORD(lParam), HIWORD(lParam), (DWORD)wParam);
case WM_MOUSEMOVE:
return pThis->OnMouseMove(LOWORD(lParam), HIWORD(lParam), (DWORD)wParam);
case WM_SETCURSOR:
return pThis->OnSetCursor((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
case WM_SETFOCUS:
SetFocus(GetDlgItem(hwnd, IDM_MENUITEM0 + rgdwPosition[pThis->m_iSelectedItem]));
return TRUE;
case WM_TIMER:
if (LAUNCHTIMER == wParam)
{
KillTimer(hwnd, LAUNCHTIMER);
pThis->OnLaunchApp();
return TRUE;
}
break;
case WM_COMMAND:
case WM_SYSCOMMAND:
if ( pThis->OnCommand(LOWORD(wParam)) )
return 0;
break;
case WM_DRAWITEM:
return pThis->OnDrawItem((UINT)wParam, (LPDRAWITEMSTRUCT)lParam);
case WM_QUERYNEWPALETTE:
return pThis->OnQueryNewPalette();
case WM_PALETTECHANGED:
return pThis->OnPaletteChanged((HWND)wParam);
case ARM_CHANGESCREEN:
return pThis->OnChangeScreen((DWORD)wParam);
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
/**
* This method is called on WM_CREATE.
*
* @param hwnd Window handle for the application.
*
* @return No return value.
*/
LRESULT CDlgApp::OnCreate(HWND hwnd)
{
m_hwnd = hwnd;
_CreateMenu();
_RedrawMenu();
SetFocus(GetDlgItem(m_hwnd, IDM_MENUITEM0 + rgdwPosition[m_iSelectedItem]));
return 0;
}
void CDlgApp::_CreateMenu()
{
// Create one window for each button. These windows will get resized and moved
// after we call AdjustToFitFonts.
for (UINT i = 0; i < ARRAYSIZE(rgPtIcons); i++)
{
HWND hwnd = CreateWindowEx(
0,
TEXT("BUTTON"),
TEXT(""),
WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON|BS_MULTILINE|BS_OWNERDRAW,
0,0,0,0,
m_hwnd,
NULL,
m_hInstance,
NULL );
SetWindowLongPtr(hwnd, GWLP_ID, IDM_MENUITEM0 + i);
SendMessage(hwnd, WM_SETFONT, (WPARAM)m_hfontMenu, 0);
g_fnBtnProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)s_ButtonWndProc);
}
// We created the windows with zero size, now we adjust that size to take into
// account for the selected font size, etc.
_AdjustIconPlacement();
_AdjustToFitFonts();
}
void CDlgApp::_RedrawMenu()
{
for (UINT i = 0; i < ARRAYSIZE(rgPtIcons); i++)
{
if (EMPTY != rgdwMenuByPos[m_dwScreen][i])
{
TCHAR szBuffer[100];
LoadString(m_hInstance, rgdwLabel[rgdwMenuByPos[m_dwScreen][i]], szBuffer, ARRAYSIZE(szBuffer));
SetWindowText(GetDlgItem(m_hwnd, IDM_MENUITEM0+i), szBuffer);
EnableWindow(GetDlgItem(m_hwnd, IDM_MENUITEM0+i), TRUE);
ShowWindow(GetDlgItem(m_hwnd, IDM_MENUITEM0+i), TRUE);
}
else
{
EnableWindow(GetDlgItem(m_hwnd, IDM_MENUITEM0+i), FALSE);
ShowWindow(GetDlgItem(m_hwnd, IDM_MENUITEM0+i), FALSE);
}
// setting window text only actually sets the accelerator, real drawing of text is in OnDrawItem
}
_AdjustToFitFonts();
}
/**
* This method handles the WM_DESTROY message.
*
* @return No return value.
*/
LRESULT CDlgApp::OnDestroy()
{
// ensure this is the last message we care about
SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
PostQuitMessage(0);
return 0;
}
LRESULT CDlgApp::OnActivate(WPARAM wParam)
{
return 0;
}
/**
* This method handles the WM_PAINT message.
*
* @return No return value.
*/
LRESULT CDlgApp::OnPaint(HDC hdc)
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd,&ps);
RECT rect;
HPALETTE hpalOld = NULL;
if ( m_hpal )
{
hpalOld = SelectPalette(hdc, m_hpal, FALSE);
RealizePalette(hdc);
}
SetMapMode(hdc, MM_TEXT);
_PaintFlagBitmap();
_DrawMenuIcons(FALSE);
// restore the DC to its original value
if(hpalOld)
SelectPalette(hdc, hpalOld, FALSE);
EndPaint(m_hwnd,&ps);
return 0;
}
/**
* This method handles the WM_ERASEBKGND message.
*
* @return No return value.
*/
LRESULT CDlgApp::OnEraseBkgnd(HDC hdc)
{
RECT rect;
HPALETTE hpalOld = NULL;
if ( m_hpal )
{
hpalOld = SelectPalette(hdc, m_hpal, FALSE);
RealizePalette(hdc);
}
SetMapMode(hdc, MM_TEXT);
SetBkMode(hdc, TRANSPARENT);
// Draw the top pane:
rect.left = 0;
rect.top = 0;
rect.right = m_cxClient;
rect.bottom = m_cxTopPanel;
if (m_f8by6 && !m_fLowColor)
{
BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, m_hdcGradientTop, 0,0, SRCCOPY );
}
else if (m_f8by6 && m_fLowColor && (m_iColors > 16))
{
BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, m_hdcGradientTop256, 0,0, SRCCOPY );
}
else
{
FillRect(hdc, &rect, m_hbrPanel);
}
// Draw center pane
rect.left = 0;
rect.top = m_cxTopPanel;
rect.right = m_cxClient;
rect.bottom = m_cyBottomPanel;
FillRect(hdc, &rect, m_hbrCenter);
// Draw the bottom pane:
rect.left = 0;
rect.top = m_cyBottomPanel;
rect.right = m_cxClient;
rect.bottom = m_cyClient;
if (m_f8by6 && !m_fLowColor)
{
BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + 1, m_hdcGradientBottom, 0,0, SRCCOPY );
}
else if (m_f8by6 && m_fLowColor && (m_iColors > 16))
{
BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + 1, m_hdcGradientBottom256, 0,0, SRCCOPY );
}
else
{
FillRect(hdc, &rect, m_hbrPanel);
}
// Draw the text
_DrawText(hdc);
if(hpalOld)
{
SelectPalette(hdc, hpalOld, FALSE);
}
return TRUE;
}
void CDlgApp::_DrawText(HDC hdc)
{
HFONT* rgFontText[4] = {&m_hfontTitle, &m_hfontHeader, &m_hfontText, &m_hfontText};
BOOL rgfShadowText[4] = {FALSE, TRUE, FALSE, FALSE};
SetTextColor(hdc,m_crNormalText);
HFONT hfontOld = (HFONT)SelectObject(hdc,m_hfontHeader); // first draw uses hfontHeader
for (int i = TEXT_TITLE; i <= TEXT_SUB; i++)
{
TCHAR szBuffer[2048];
SelectObject(hdc, *rgFontText[i]);
LoadString(m_hInstance, rgdwText[m_dwScreen][i], szBuffer, ARRAYSIZE(szBuffer));
if (rgfShadowText[i] && !m_fHighContrast)
{
SetTextColor(hdc,m_crShadow);
RECT rectShadow;
memcpy(&rectShadow, (m_f8by6) ? &(rgrectText[i]) : &(rgrectText640[i]), sizeof(rectShadow));
rectShadow.left += 2; rectShadow.right += 2; rectShadow.top += 2; rectShadow.bottom += 2;
DrawText(hdc,szBuffer,-1, &rectShadow, DT_NOCLIP|DT_WORDBREAK);
SetTextColor(hdc,m_crTitleText);
}
DrawText(hdc,szBuffer,-1, (m_f8by6) ? &(rgrectText[i]) : &(rgrectText640[i]), DT_NOCLIP|DT_WORDBREAK);
}
// restore the DC to its original value
SelectObject(hdc,hfontOld);
}
void CDlgApp::_PaintFlagBitmap()
{
HDC hdc = GetDC(m_hwnd);
if (hdc)
{
RECT rect;
if (m_f8by6)
{
rect.left = 20;
rect.top = 10;
}
else
{
rect.left = 20;
rect.top = 20;
}
rect.right = rect.left + FLAG_WIDTH;
rect.bottom = rect.top + FLAG_HEIGHT;
BitBlt( hdc, rect.left, rect.top, FLAG_WIDTH, FLAG_HEIGHT,
Mirror_IsWindowMirroredRTL(m_hwnd) ? m_hdcFlagRTL : m_hdcFlag,
0,0, SRCCOPY); // don't mirror flag on RTL systems for trademark reasons
ReleaseDC(m_hwnd, hdc);
}
}
BOOL CDlgApp::_GetButtonIntersect(int x, int y, UINT* pidMenuItem)
{
POINT pt;
pt.x = x;
pt.y = y;
for (UINT i = 0; i < rgcMenu[m_dwScreen]; i++)
{
UINT iPos = rgdwPosition[rgdwMenu[m_dwScreen][i]];
RECT rect;
rect.left = m_f8by6 ? rgPtIcons[iPos].x : rgPtIcons640[iPos].x;
rect.top = m_f8by6 ? rgPtIcons[iPos].y : rgPtIcons640[iPos].y;
rect.right = rect.left + MENUICON_WIDTH;
rect.bottom = rect.top + MENUICON_HEIGHT;
// extend the "hot zone" of the button to the right of the button by this amount to close the gap
// between the button and the menu item
switch (rgdwMenu[m_dwScreen][i])
{
case EXIT_DEX:
case BACK_DEX:
case NEXT_DEX:
case FINISH_DEX:
rect.left -= 6; // for items with text to the left of the button, we extend to the left
break;
case LINK_DEX:
case RADIO_1_DEX:
case RADIO_0_DEX:
rect.right += 6; // for items with text to the right of the button, we extend to the right
}
if (PtInRect(&rect, pt))
{
*pidMenuItem = IDM_MENUITEM0 + iPos;
return TRUE;
}
}
return FALSE;
}
LRESULT CDlgApp::OnMouseMove(int x, int y, DWORD fwKeys)
{
if (GetForegroundWindow() == m_hwnd) // only care if we have focus
{
UINT idMenuItem;
if (_GetButtonIntersect(x, y, &idMenuItem))
{
SetFocus(GetDlgItem(m_hwnd, idMenuItem));
SetCursor(m_hcurHand);
}
else
{
SetCursor(LoadCursor(NULL,IDC_ARROW));
}
}
return 0;
}
LRESULT CDlgApp::OnLButtonUp(int x, int y, DWORD fwKeys)
{
if (GetForegroundWindow() == m_hwnd) // only care if we have focus
{
UINT idMenuItem;
if (_GetButtonIntersect(x, y, &idMenuItem))
{
OnCommand(idMenuItem);
}
}
return 0;
}
LRESULT CDlgApp::OnSetCursor(HWND hwnd, int nHittest, int wMouseMsg)
{
if (GetForegroundWindow() == m_hwnd) // only care if we have focus
{
if ( hwnd != m_hwnd )
{
SetCursor(m_hcurHand);
return TRUE;
}
SetCursor(LoadCursor(NULL,IDC_ARROW));
}
return TRUE;
}
LRESULT CDlgApp::OnChangeScreen(DWORD dwScreen)
{
static DWORD dwSelectedOld; // we store the last position on the main screen
m_dwScreen += dwScreen;
_RedrawMenu();
HDC hdc = GetDC(m_hwnd);
if (hdc)
{
_DrawText(hdc);
ReleaseDC(m_hwnd, hdc);
}
// invalidate the text
_InvalidateRectIntl(m_hwnd, NULL, TRUE);
m_iSelectedItem = rgdwMenuByPos[m_dwScreen][rgdwPosition[m_iSelectedItem]];
if (EMPTY == m_iSelectedItem)
{
m_iSelectedItem = rgdwMenu[m_dwScreen][rgcMenu[m_dwScreen] - 1];
SetFocus(GetDlgItem(m_hwnd, IDM_MENUITEM0 + rgdwPosition[m_iSelectedItem]));
}
return TRUE;
}
LRESULT CDlgApp::OnLaunchApp()
{
BOOL fResult = FALSE;
TCHAR szDirectory[MAX_PATH];
// first, pop up the "please wait" dialog
HWND hwndWait = CreateDialog(m_hInstance, MAKEINTRESOURCE(IDD_WAIT), GetDesktopWindow(), (DLGPROC)s_WaitWndProc);
if (hwndWait)
{
RECT popupSize = {0, 0, 175, 50}; // a good guess
GetWindowRect(hwndWait, &popupSize);
SetWindowPos(hwndWait, HWND_TOP,
(m_cDesktopWidth - (popupSize.right - popupSize.left)) / 2 ,
(m_cDesktopHeight - (popupSize.bottom - popupSize.top)) / 2,
0, 0, SWP_SHOWWINDOW | SWP_NOSIZE);
}
// then launch the app itself
if (GetModuleFileName(NULL, szDirectory, ARRAYSIZE(szDirectory)) &&
_PathRemoveFileSpec(szDirectory))
{
TCHAR szBuffer[256];
TCHAR szArgsBuffer[256];
LoadStringAuto(m_hInstance, IDS_EXECUTABLE, szBuffer, ARRAYSIZE(szBuffer));
LoadStringAuto(m_hInstance,
m_fDynamicUpdate ? IDS_EXECUTABLE_ARGS_DU : IDS_EXECUTABLE_ARGS_NODU,
szArgsBuffer, ARRAYSIZE(szArgsBuffer));
fResult = ((INT_PTR)ShellExecute(m_hwnd, NULL, szBuffer, szArgsBuffer, szDirectory, SW_SHOWNORMAL ) > 32);
}
return fResult;
}
LRESULT CDlgApp::OnNextButton()
{
switch (m_dwScreen)
{
case 4: // on change to last screen, we launch the app
SetTimer(m_hwnd, LAUNCHTIMER, 100, NULL);
break;
}
return TRUE;
}
LRESULT CDlgApp::OnCommand(int wID)
{
BOOL fRetVal = FALSE;
switch(wID)
{
case IDM_MENUITEM0:
case IDM_MENUITEM1:
case IDM_MENUITEM2:
case IDM_MENUITEM3:
case IDM_MENUITEM4:
switch (rgdwMenuByPos[m_dwScreen][wID-IDM_MENUITEM0])
{
case EXIT_DEX:
case FINISH_DEX:
PostQuitMessage(0);
fRetVal = TRUE;
break;
case BACK_DEX:
OnChangeScreen(-1);
fRetVal = TRUE;
break;
case NEXT_DEX:
OnNextButton();
OnChangeScreen(+1);
fRetVal = TRUE;
break;
case RADIO_1_DEX:
m_fDynamicUpdate = TRUE;
_DrawMenuIcons(FALSE);
break;
case RADIO_0_DEX:
m_fDynamicUpdate = FALSE;
_DrawMenuIcons(FALSE);
break;
case LINK_DEX:
{
TCHAR szLinkBuffer[256];
LoadStringAuto( m_hInstance, IDS_LINK, szLinkBuffer, ARRAYSIZE(szLinkBuffer) );
ShellExecute(m_hwnd, NULL, szLinkBuffer, NULL, NULL, SW_SHOWNORMAL);
}
break;
}
break;
}
return fRetVal;
}
LRESULT CDlgApp::OnQueryNewPalette()
{
if ( m_hpal )
{
HDC hdc = GetDC(m_hwnd);
if (hdc)
{
HPALETTE hpalOld = SelectPalette(hdc, m_hpal, FALSE);
UnrealizeObject(m_hpal);
RealizePalette(hdc);
UpdateWindow(m_hwnd);
if(hpalOld)
SelectPalette(hdc, hpalOld, FALSE);
ReleaseDC(m_hwnd, hdc);
}
return TRUE;
}
return FALSE;
}
LRESULT CDlgApp::OnPaletteChanged(HWND hwnd)
{
if ( m_hpal && (m_hwnd != hwnd) )
{
HDC hdc = GetDC(m_hwnd);
if (hdc)
{
HPALETTE hpalOld = SelectPalette(hdc, m_hpal, FALSE);
RealizePalette(hdc);
UpdateColors(hdc);
if (hpalOld)
SelectPalette(hdc, hpalOld, FALSE);
ReleaseDC(m_hwnd, hdc);
}
}
return TRUE;
}
LRESULT CDlgApp::OnDrawItem(UINT iCtlID, LPDRAWITEMSTRUCT pdis)
{
UINT dex = iCtlID - IDM_MENUITEM0;
RECT rect = pdis->rcItem;
POINT rectAbs = m_f8by6 ? rgPtIconText[dex] : rgPtIconText640[dex];
HPALETTE hpalOld = NULL;
TCHAR szBuffer[256];
SIZE size;
LoadString(m_hInstance, rgdwLabel[rgdwMenuByPos[m_dwScreen][dex]], szBuffer, ARRAYSIZE(szBuffer));
INT iLogPixelSx = GetDeviceCaps(pdis->hDC, LOGPIXELSX);
INT iLogPixelSy = GetDeviceCaps(pdis->hDC, LOGPIXELSY);
GetTextExtentPoint32(pdis->hDC, szBuffer, lstrlen(szBuffer), &size);
size.cx = (size.cx * iLogPixelSx) / 80;
size.cy = (size.cy * iLogPixelSy) / 80;
if ( m_hpal )
{
hpalOld = SelectPalette(pdis->hDC, m_hpal, FALSE);
RealizePalette(pdis->hDC);
}
if (LINK_DEX == rgdwMenuByPos[m_dwScreen][dex] ||
RADIO_1_DEX == rgdwMenuByPos[m_dwScreen][dex] ||
RADIO_0_DEX == rgdwMenuByPos[m_dwScreen][dex])
{
FillRect(pdis->hDC, &rect, m_hbrCenter);
}
else if (m_f8by6 && !m_fLowColor)
{
BitBlt(pdis->hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, m_hdcGradientBottom, rectAbs.x, rectAbs.y - m_cyBottomPanel, SRCCOPY);
}
else if (m_f8by6 && m_fLowColor && (m_iColors > 16))
{
BitBlt(pdis->hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, m_hdcGradientBottom256, rectAbs.x, rectAbs.y - m_cyBottomPanel, SRCCOPY);
}
else
{
FillRect(pdis->hDC, &rect, m_hbrPanel);
}
SetBkMode(pdis->hDC, TRANSPARENT);
SetTextColor(pdis->hDC,m_crNormalText);
UINT nFormat = DT_NOCLIP | DT_WORDBREAK;
if (BACK_DEX == rgdwMenuByPos[m_dwScreen][dex] ||
NEXT_DEX == rgdwMenuByPos[m_dwScreen][dex] ||
EXIT_DEX == rgdwMenuByPos[m_dwScreen][dex] ||
FINISH_DEX == rgdwMenuByPos[m_dwScreen][dex])
{
nFormat |= DT_RIGHT;
}
DrawText(pdis->hDC, szBuffer,-1, &rect, nFormat);
if ( pdis->itemState & ODS_FOCUS )
{
if ( m_fHighContrast )
{
rect.left -= 1;
rect.top -= 2;
rect.right += 1;
rect.bottom -= 2;
DrawFocusRect(pdis->hDC,&rect);
}
}
if ( hpalOld )
{
SelectPalette(pdis->hDC, hpalOld, FALSE);
}
_DrawMenuIcons(FALSE);
return TRUE;
}
LRESULT CALLBACK CDlgApp::s_ButtonWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CDlgApp *pThis = (CDlgApp *)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
int iID = ((int)GetWindowLongPtr(hwnd, GWLP_ID)) - IDM_MENUITEM0;
switch (uMsg)
{
case WM_ERASEBKGND:
return TRUE;
break;
case WM_MOUSEMOVE:
if (GetForegroundWindow() == GetParent(hwnd))
{
int iCurrDex = rgdwMenuByPos[pThis->m_dwScreen][iID];
if ( iCurrDex != pThis->m_iSelectedItem )
{
SetFocus(hwnd);
}
}
else
{
return FALSE;
}
break;
case WM_SETFOCUS:
if (GetForegroundWindow() == GetParent(hwnd))
{
int iCurrDex = rgdwMenuByPos[pThis->m_dwScreen][iID];
if (EMPTY != iCurrDex &&
pThis->m_iSelectedItem != iCurrDex)
{
pThis->m_iSelectedItem = iCurrDex;
SetFocus(GetDlgItem(GetParent(hwnd), IDM_MENUITEM0+iID));
}
}
else
{
return FALSE;
}
break;
}
return CallWindowProc(g_fnBtnProc, hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK CDlgApp::s_WaitWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
SetTimer(hwnd, WAITTIMER, 10000, NULL);
return TRUE;
break;
case WM_TIMER:
if (WAITTIMER == wParam)
{
PostMessage(GetParent(hwnd), WM_SETFOCUS, NULL, NULL);
DestroyWindow(hwnd);
return TRUE;
}
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}