1528 lines
44 KiB
C++
1528 lines
44 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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);
|
|
}
|