You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2115 lines
54 KiB
2115 lines
54 KiB
//
|
|
// arcdlg.cpp: Autoreconnect dialog box
|
|
// modeless dialog box for autoreconnection status
|
|
//
|
|
// Copyright Microsoft Corportation 2001
|
|
// (nadima)
|
|
//
|
|
|
|
#include "adcg.h"
|
|
|
|
#define TRC_GROUP TRC_GROUP_UI
|
|
#define TRC_FILE "arcdlg.cpp"
|
|
#include <atrcapi.h>
|
|
|
|
#include "arcdlg.h"
|
|
#include "axresrc.h"
|
|
|
|
#define TRANSPARENT_MASK_COLOR RGB(105, 139, 228)
|
|
|
|
#ifdef OS_WINCE
|
|
#define RGB_TOPBAND RGB(0, 52, 156)
|
|
#define RGB_MIDBAND RGB(49,101,206)
|
|
#endif
|
|
|
|
//
|
|
// Runtime debug flags instrumentation for 611316
|
|
//
|
|
#define ARCDLG_DEBUG_DESTROYCALLED 0x0001
|
|
#define ARCDLG_DEBUG_WMDESTROYCALLED 0x0002
|
|
#define ARCDLG_DEBUG_WMDESTROYSUCCEED 0x0004
|
|
#define ARCDLG_DEBUG_SETNULLINSTPTR 0x0008
|
|
DWORD g_dwArcDlgDebug = 0;
|
|
#define ARC_DBG_SETINFO(x) g_dwArcDlgDebug |= x;
|
|
|
|
LPTSTR
|
|
FormatMessageVArgs(LPCTSTR pcszFormat, ...)
|
|
|
|
{
|
|
LPTSTR pszOutput;
|
|
va_list argList;
|
|
|
|
va_start(argList, pcszFormat);
|
|
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
|
|
pcszFormat,
|
|
0, 0,
|
|
reinterpret_cast<LPTSTR>(&pszOutput), 0,
|
|
&argList) == 0)
|
|
{
|
|
pszOutput = NULL;
|
|
}
|
|
|
|
va_end(argList);
|
|
return(pszOutput);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ARC UI base class
|
|
//
|
|
CAutoReconnectUI::CAutoReconnectUI(
|
|
HWND hwndOwner,
|
|
HINSTANCE hInst,
|
|
CUI* pUi) :
|
|
_hwndOwner(hwndOwner),
|
|
_hInstance(hInst),
|
|
_hwnd(NULL),
|
|
_pUi(pUi)
|
|
{
|
|
DC_BEGIN_FN("CAutoReconnectUI");
|
|
|
|
#ifndef OS_WINCE
|
|
_hGDI = LoadLibrary(_T("gdi32.dll"));
|
|
if (_hGDI) {
|
|
_pfnSetLayout = (PFNGDI_SETLAYOUT)GetProcAddress(_hGDI, "SetLayout");
|
|
if (!_pfnSetLayout) {
|
|
TRC_ERR((TB,_T("GetProcAddress 'SetLayout' failed: 0x%x"),
|
|
GetLastError()));
|
|
}
|
|
}
|
|
#else
|
|
_hGDI = NULL;
|
|
_pfnSetLayout = NULL;
|
|
#endif
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
CAutoReconnectUI::~CAutoReconnectUI()
|
|
{
|
|
DC_BEGIN_FN("CAutoReconnectUI");
|
|
|
|
#ifndef OS_WINCE
|
|
if (_hGDI) {
|
|
_pfnSetLayout = NULL;
|
|
FreeLibrary(_hGDI);
|
|
_hGDI = NULL;
|
|
}
|
|
#endif
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
//
|
|
// PaintBitmap
|
|
//
|
|
// Params: hdcDestination = HDC to paint into.
|
|
// prcDestination = RECT in HDC to paint into.
|
|
// hbmSource = HBITMAP to paint.
|
|
// prcSource = RECT from HBITMAP to paint from.
|
|
//
|
|
// Returns: <none>
|
|
//
|
|
// Purpose: Wraps blitting a bitmap.
|
|
//
|
|
// Modified from version in shell code
|
|
//
|
|
VOID
|
|
CAutoReconnectUI::PaintBitmap(
|
|
HDC hdcDestination,
|
|
const RECT* prcDestination,
|
|
HBITMAP hbmSource,
|
|
const RECT *prcSource
|
|
)
|
|
{
|
|
HDC hdcBitmap;
|
|
|
|
DC_BEGIN_FN("PaintBitmap");
|
|
|
|
hdcBitmap = CreateCompatibleDC(NULL);
|
|
if (hdcBitmap != NULL)
|
|
{
|
|
BOOL fEqualWidthAndHeight;
|
|
INT iWidthSource, iHeightSource;
|
|
INT iWidthDestination, iHeightDestination;
|
|
INT iStretchBltMode;
|
|
#ifndef OS_WINCE
|
|
DWORD dwLayout;
|
|
#endif
|
|
HBITMAP hbmSelected;
|
|
RECT rcSource;
|
|
BITMAP bitmap;
|
|
|
|
if (prcSource == NULL)
|
|
{
|
|
if (GetObject(hbmSource, sizeof(bitmap), &bitmap) == 0)
|
|
{
|
|
bitmap.bmWidth = prcDestination->right - prcDestination->left;
|
|
bitmap.bmHeight = prcDestination->bottom - prcDestination->top;
|
|
}
|
|
SetRect(&rcSource, 0, 0, bitmap.bmWidth, bitmap.bmHeight);
|
|
prcSource = &rcSource;
|
|
}
|
|
hbmSelected = static_cast<HBITMAP>(SelectObject(hdcBitmap, hbmSource));
|
|
iWidthSource = prcSource->right - prcSource->left;
|
|
iHeightSource = prcSource->bottom - prcSource->top;
|
|
iWidthDestination = prcDestination->right - prcDestination->left;
|
|
iHeightDestination = prcDestination->bottom - prcDestination->top;
|
|
fEqualWidthAndHeight = (iWidthSource == iWidthDestination) &&
|
|
(iHeightSource == iHeightDestination);
|
|
if (!fEqualWidthAndHeight) {
|
|
#ifndef OS_WINCE
|
|
iStretchBltMode = SetStretchBltMode(hdcDestination, HALFTONE);
|
|
#endif
|
|
}
|
|
else {
|
|
iStretchBltMode = 0;
|
|
}
|
|
|
|
#ifndef OS_WINCE
|
|
if (_pfnSetLayout) {
|
|
dwLayout = _pfnSetLayout(hdcDestination,
|
|
LAYOUT_BITMAPORIENTATIONPRESERVED);
|
|
}
|
|
#endif
|
|
if (!StretchBlt(hdcDestination,
|
|
prcDestination->left,
|
|
prcDestination->top,
|
|
iWidthDestination,
|
|
iHeightDestination,
|
|
hdcBitmap,
|
|
prcSource->left,
|
|
prcSource->top,
|
|
iWidthSource,
|
|
iHeightSource,
|
|
SRCCOPY)) {
|
|
TRC_ERR((TB,_T("Blt failed")));
|
|
}
|
|
|
|
#ifndef OS_WINCE
|
|
if (_pfnSetLayout) {
|
|
_pfnSetLayout(hdcDestination, dwLayout);
|
|
}
|
|
|
|
if (!fEqualWidthAndHeight) {
|
|
(int)SetStretchBltMode(hdcDestination, iStretchBltMode);
|
|
}
|
|
#endif
|
|
(HGDIOBJ)SelectObject(hdcBitmap, hbmSelected);
|
|
DeleteDC(hdcBitmap);
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
|
|
VOID
|
|
CAutoReconnectUI::CenterWindow(
|
|
HWND hwndCenterOn,
|
|
INT xRatio,
|
|
INT yRatio
|
|
)
|
|
{
|
|
RECT childRect;
|
|
RECT parentRect;
|
|
DCINT xPos;
|
|
DCINT yPos;
|
|
|
|
LONG desktopX = GetSystemMetrics(SM_CXSCREEN);
|
|
LONG desktopY = GetSystemMetrics(SM_CYSCREEN);
|
|
|
|
BOOL center = TRUE;
|
|
|
|
DC_BEGIN_FN("CenterWindowOnParent");
|
|
|
|
TRC_ASSERT(_hwnd, (TB, _T("_hwnd is NULL...was it set in WM_INITDIALOG?\n")));
|
|
if (!_hwnd)
|
|
{
|
|
TRC_ALT((TB, _T("Window doesn't exist")));
|
|
DC_QUIT;
|
|
}
|
|
if (!xRatio)
|
|
{
|
|
xRatio = 2;
|
|
}
|
|
if (!yRatio)
|
|
{
|
|
yRatio = 2;
|
|
}
|
|
|
|
GetClientRect(hwndCenterOn, &parentRect);
|
|
GetWindowRect(_hwnd, &childRect);
|
|
|
|
//
|
|
// Calculate the top left - centered in the parent window.
|
|
//
|
|
xPos = ( (parentRect.right + parentRect.left) -
|
|
(childRect.right - childRect.left)) / xRatio;
|
|
yPos = ( (parentRect.bottom + parentRect.top) -
|
|
(childRect.bottom - childRect.top)) / yRatio;
|
|
|
|
//
|
|
// Constrain to the desktop
|
|
//
|
|
if (xPos < 0)
|
|
{
|
|
xPos = 0;
|
|
}
|
|
else if (xPos > (desktopX - (childRect.right - childRect.left)))
|
|
{
|
|
xPos = desktopX - (childRect.right - childRect.left);
|
|
}
|
|
if (yPos < 0)
|
|
{
|
|
yPos = 0;
|
|
}
|
|
else if (yPos > (desktopY - (childRect.bottom - childRect.top)))
|
|
{
|
|
yPos = desktopY - (childRect.bottom - childRect.top);
|
|
}
|
|
|
|
TRC_DBG((TB, _T("Set dialog position to %u %u"), xPos, yPos));
|
|
SetWindowPos(_hwnd,
|
|
NULL,
|
|
xPos, yPos,
|
|
0, 0,
|
|
SWP_NOSIZE | SWP_NOACTIVATE);
|
|
|
|
DC_EXIT_POINT:
|
|
DC_END_FN();
|
|
|
|
return;
|
|
} // CenterWindowOnParent
|
|
|
|
|
|
#ifndef ARC_MINIMAL_UI
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ARC UI - Rich UI - dialog with status text and progress band
|
|
//
|
|
|
|
CAutoReconnectDlg::CAutoReconnectDlg(HWND hwndOwner,
|
|
HINSTANCE hInst,
|
|
CUI* pUi) :
|
|
CAutoReconnectUI(hwndOwner, hInst, pUi),
|
|
_fInitialized(FALSE),
|
|
_hfntTitle(NULL),
|
|
_pProgBand(NULL),
|
|
_hPalette(NULL)
|
|
{
|
|
#ifndef OS_WINCE
|
|
BOOL fUse8BitDepth = FALSE;
|
|
#else
|
|
BOOL fUse8BitDepth = TRUE;
|
|
#endif
|
|
LOGFONT logFont;
|
|
#ifndef OS_WINCE
|
|
HDC hdcScreen;
|
|
char szPixelSize[10];
|
|
#else
|
|
WCHAR szPixelSize[10];
|
|
#endif
|
|
BITMAP bitmap;
|
|
INT logPixelsY = 100;
|
|
|
|
DC_BEGIN_FN("CAutoReconnectDlg");
|
|
|
|
_nArcTimerID = 0;
|
|
_elapsedArcTime = 0;
|
|
_fContinueReconAttempts = TRUE;
|
|
|
|
#ifndef OS_WINCE
|
|
//
|
|
// Get color depth
|
|
//
|
|
hdcScreen = GetDC(NULL);
|
|
if (hdcScreen) {
|
|
fUse8BitDepth = (GetDeviceCaps(hdcScreen, BITSPIXEL) <= 8);
|
|
logPixelsY = GetDeviceCaps(hdcScreen, LOGPIXELSY);
|
|
ReleaseDC(NULL, hdcScreen);
|
|
hdcScreen = NULL;
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Load bitmaps
|
|
//
|
|
_hbmBackground = (HBITMAP)LoadImage(
|
|
_hInstance,
|
|
MAKEINTRESOURCE(fUse8BitDepth ?
|
|
IDB_ARC_BACKGROUND8 :IDB_ARC_BACKGROUND24),
|
|
IMAGE_BITMAP,
|
|
0,
|
|
0,
|
|
#ifndef OS_WINCE
|
|
LR_CREATEDIBSECTION);
|
|
#else
|
|
0);
|
|
#endif
|
|
if ((_hbmBackground != NULL) &&
|
|
(GetObject(_hbmBackground,
|
|
sizeof(bitmap), &bitmap) >= sizeof(bitmap))) {
|
|
SetRect(&_rcBackground, 0, 0, bitmap.bmWidth, bitmap.bmHeight);
|
|
}
|
|
|
|
_hbmFlag = (HBITMAP)LoadImage(
|
|
_hInstance,
|
|
MAKEINTRESOURCE(fUse8BitDepth ?
|
|
IDB_ARC_WINFLAG8 :IDB_ARC_WINFLAG24),
|
|
IMAGE_BITMAP,
|
|
0,
|
|
0,
|
|
#ifndef OS_WINCE
|
|
LR_CREATEDIBSECTION);
|
|
#else
|
|
0);
|
|
#endif
|
|
if ((_hbmFlag != NULL) &&
|
|
(GetObject(_hbmFlag,
|
|
sizeof(bitmap), &bitmap) >= sizeof(bitmap))) {
|
|
SetRect(&_rcFlag, 0, 0, bitmap.bmWidth, bitmap.bmHeight);
|
|
}
|
|
|
|
#ifndef OS_WINCE
|
|
_hbmDisconImg = (HBITMAP)LoadImage(
|
|
_hInstance,
|
|
MAKEINTRESOURCE(fUse8BitDepth ?
|
|
IDB_ARC_DISCON8 :IDB_ARC_DISCON24),
|
|
IMAGE_BITMAP,
|
|
0,
|
|
0,
|
|
LR_CREATEDIBSECTION);
|
|
if ((_hbmDisconImg != NULL) &&
|
|
(GetObject(_hbmDisconImg,
|
|
sizeof(bitmap), &bitmap) >= sizeof(bitmap))) {
|
|
SetRect(&_rcDisconImg, 0, 0, bitmap.bmWidth, bitmap.bmHeight);
|
|
}
|
|
|
|
_hPalette = CUT::UT_GetPaletteForBitmap(NULL, _hbmBackground);
|
|
#endif
|
|
|
|
|
|
//
|
|
// Create fonts. Load the font name and size from resources.
|
|
//
|
|
|
|
ZeroMemory(&logFont, sizeof(logFont));
|
|
#ifndef OS_WINCE
|
|
if (LoadStringA(_hInstance,
|
|
IDS_ARC_TITLE_FACESIZE,
|
|
szPixelSize,
|
|
sizeof(szPixelSize)) != 0)
|
|
#else
|
|
if (LoadString(_hInstance,
|
|
IDS_ARC_TITLE_FACESIZE,
|
|
szPixelSize,
|
|
sizeof(szPixelSize)/sizeof(WCHAR)) != 0)
|
|
#endif
|
|
{
|
|
#ifndef OS_WINCE
|
|
logFont.lfHeight = -MulDiv(atoi(szPixelSize),
|
|
logPixelsY, 72);
|
|
#else
|
|
logFont.lfHeight = -(_wtoi(szPixelSize)/logPixelsY*72);
|
|
#endif
|
|
if (LoadString(_hInstance,
|
|
IDS_ARC_TITLE_FACENAME,
|
|
logFont.lfFaceName,
|
|
LF_FACESIZE) != 0)
|
|
{
|
|
logFont.lfWeight = FW_BOLD;
|
|
logFont.lfQuality = DEFAULT_QUALITY;
|
|
_hfntTitle = CreateFontIndirect(&logFont);
|
|
}
|
|
}
|
|
|
|
_szConnectAttemptStringTmpl[0] = NULL;
|
|
if (!LoadString(_hInstance,
|
|
IDS_ARC_CONATTEMPTS,
|
|
_szConnectAttemptStringTmpl,
|
|
sizeof(_szConnectAttemptStringTmpl)/sizeof(TCHAR)) != 0)
|
|
{
|
|
TRC_ERR((TB,_T("Failed to load IDS_ARC_CONATTEMPTS")));
|
|
}
|
|
|
|
_lastDiscReason = NL_DISCONNECT_LOCAL;
|
|
|
|
#ifdef OS_WINCE
|
|
_hbrTopBand = CreateSolidBrush(RGB_TOPBAND);
|
|
_hbrMidBand = CreateSolidBrush(RGB_MIDBAND);
|
|
#endif
|
|
|
|
|
|
_fInitialized = (_hbmBackground &&
|
|
_hbmFlag &&
|
|
_hfntTitle &&
|
|
_pUi &&
|
|
_szConnectAttemptStringTmpl[0]);
|
|
if (!_fInitialized) {
|
|
TRC_ERR((TB,_T("Failed to properly init arc dlg")));
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
CAutoReconnectDlg::~CAutoReconnectDlg()
|
|
{
|
|
if (_hbmBackground) {
|
|
DeleteObject(_hbmBackground);
|
|
_hbmBackground = NULL;
|
|
}
|
|
|
|
if (_hbmFlag) {
|
|
DeleteObject(_hbmFlag);
|
|
_hbmFlag = NULL;
|
|
}
|
|
|
|
#ifndef OS_WINCE
|
|
if (_hbmDisconImg) {
|
|
DeleteObject(_hbmDisconImg);
|
|
_hbmDisconImg = NULL;
|
|
}
|
|
#endif
|
|
|
|
if (_hfntTitle) {
|
|
DeleteObject(_hfntTitle);
|
|
_hfntTitle = NULL;
|
|
}
|
|
|
|
if (_hPalette) {
|
|
DeleteObject(_hPalette);
|
|
_hPalette = NULL;
|
|
}
|
|
|
|
if (_pProgBand) {
|
|
delete _pProgBand;
|
|
_pProgBand = NULL;
|
|
}
|
|
|
|
#ifdef OS_WINCE
|
|
if (_hbrTopBand) {
|
|
DeleteObject(_hbrTopBand);
|
|
_hbrTopBand = NULL;
|
|
}
|
|
|
|
if (_hbrMidBand) {
|
|
DeleteObject(_hbrMidBand);
|
|
_hbrMidBand = NULL;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
HWND CAutoReconnectDlg::StartModeless()
|
|
{
|
|
LONG_PTR dwStyle;
|
|
DC_BEGIN_FN("StartModeless");
|
|
|
|
if (!_fInitialized) {
|
|
TRC_ERR((TB,_T("failing startmodeless fInitialized is FALSE")));
|
|
return NULL;
|
|
}
|
|
|
|
_hwnd = CreateDialogParam(_hInstance,
|
|
MAKEINTRESOURCE(IDD_ARCDLG),
|
|
_hwndOwner,
|
|
StaticDialogBoxProc,
|
|
(LPARAM)this);
|
|
|
|
if (_hwnd) {
|
|
//
|
|
// Make the dialog a child of the parent
|
|
//
|
|
dwStyle = GetWindowLongPtr(_hwnd, GWL_STYLE);
|
|
dwStyle &= ~WS_POPUP;
|
|
dwStyle |= WS_CHILD;
|
|
SetParent(_hwnd, _hwndOwner);
|
|
SetWindowLongPtr(_hwnd, GWL_STYLE, dwStyle);
|
|
}
|
|
else {
|
|
TRC_ERR((TB,_T("CreateDialog failed: 0x%x"), GetLastError()));
|
|
}
|
|
|
|
DC_END_FN();
|
|
return _hwnd;
|
|
}
|
|
|
|
BOOL CAutoReconnectDlg::ShowTopMost()
|
|
{
|
|
BOOL rc = FALSE;
|
|
DC_BEGIN_FN("ShowTopMost");
|
|
|
|
if (!_hwnd) {
|
|
DC_QUIT;
|
|
}
|
|
|
|
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
|
|
|
//
|
|
// Bring the window to the TOP of the Z order
|
|
//
|
|
SetWindowPos( _hwnd,
|
|
HWND_TOPMOST,
|
|
0, 0, 0, 0,
|
|
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
|
|
|
|
rc = TRUE;
|
|
|
|
DC_EXIT_POINT:
|
|
DC_END_FN();
|
|
return rc;
|
|
}
|
|
|
|
VOID
|
|
CAutoReconnectDlg::OnParentSizePosChange()
|
|
{
|
|
DC_BEGIN_FN("OnParentSizePosChange");
|
|
|
|
//
|
|
// Reposition the dialog to 1/2 down the middle
|
|
// of the owner window
|
|
//
|
|
if (_hwnd && _hwndOwner) {
|
|
CenterWindow(_hwndOwner, 2, 2);
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
//
|
|
// Handler for WM_ERASEBKGND (See platform sdk docs)
|
|
//
|
|
VOID
|
|
CAutoReconnectDlg::OnEraseBkgnd(
|
|
HWND hwnd,
|
|
HDC hdc
|
|
)
|
|
{
|
|
RECT rc;
|
|
HPALETTE hPaletteOld = NULL;
|
|
DC_BEGIN_FN("OnEraseBkgnd");
|
|
|
|
TRC_ASSERT(_hbmBackground, (TB,_T("_hbmBackground is NULL")));
|
|
|
|
if (GetClientRect(hwnd, &rc)) {
|
|
|
|
hPaletteOld = SelectPalette(hdc, _hPalette, FALSE);
|
|
RealizePalette(hdc);
|
|
|
|
PaintBitmap(hdc, &rc, _hbmBackground, &_rcBackground);
|
|
|
|
SelectPalette(hdc, hPaletteOld, FALSE);
|
|
RealizePalette(hdc);
|
|
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
|
|
//
|
|
// Handler for WM_PRINTCLIENT
|
|
//
|
|
VOID
|
|
CAutoReconnectDlg::OnPrintClient(
|
|
HWND hwnd,
|
|
HDC hdcPrint,
|
|
DWORD dwOptions)
|
|
{
|
|
DC_BEGIN_FN("OnPrintClient");
|
|
|
|
#ifndef OS_WINCE
|
|
if ((dwOptions & (PRF_ERASEBKGND | PRF_CLIENT)) != 0)
|
|
{
|
|
OnEraseBkgnd(hwnd, hdcPrint);
|
|
}
|
|
#endif
|
|
DC_END_FN();
|
|
}
|
|
|
|
#ifndef OS_WINCE
|
|
void xDrawTransparentBitmap(HDC hdc, HBITMAP hBitmap, short xStart,
|
|
short yStart, COLORREF cTransparentColor)
|
|
{
|
|
BITMAP bm;
|
|
COLORREF cColor;
|
|
HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
|
|
HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
|
|
HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
|
|
POINT ptSize;
|
|
|
|
hdcTemp = CreateCompatibleDC(hdc);
|
|
SelectObject(hdcTemp, hBitmap); // Select the bitmap
|
|
|
|
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
|
|
ptSize.x = bm.bmWidth; // Get width of bitmap
|
|
ptSize.y = bm.bmHeight; // Get height of bitmap
|
|
DPtoLP(hdcTemp, &ptSize, 1); // Convert from device
|
|
|
|
// to logical points
|
|
|
|
// Create some DCs to hold temporary data.
|
|
hdcBack = CreateCompatibleDC(hdc);
|
|
hdcObject = CreateCompatibleDC(hdc);
|
|
hdcMem = CreateCompatibleDC(hdc);
|
|
hdcSave = CreateCompatibleDC(hdc);
|
|
|
|
// Create a bitmap for each DC. DCs are required for a number of
|
|
// GDI functions.
|
|
|
|
// Monochrome DC
|
|
bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
|
|
|
|
// Monochrome DC
|
|
bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
|
|
|
|
bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
|
|
bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
|
|
|
|
// Each DC must select a bitmap object to store pixel data.
|
|
bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack);
|
|
bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);
|
|
bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem);
|
|
bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave);
|
|
|
|
// Set proper mapping mode.
|
|
SetMapMode(hdcTemp, GetMapMode(hdc));
|
|
|
|
// Save the bitmap sent here, because it will be overwritten.
|
|
BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
|
|
|
|
// Set the background color of the source DC to the color.
|
|
// contained in the parts of the bitmap that should be transparent
|
|
cColor = SetBkColor(hdcTemp, cTransparentColor);
|
|
|
|
// Create the object mask for the bitmap by performing a BitBlt
|
|
// from the source bitmap to a monochrome bitmap.
|
|
BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,
|
|
SRCCOPY);
|
|
|
|
// Set the background color of the source DC back to the original
|
|
// color.
|
|
SetBkColor(hdcTemp, cColor);
|
|
|
|
// Create the inverse of the object mask.
|
|
BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,
|
|
NOTSRCCOPY);
|
|
|
|
// Copy the background of the main DC to the destination.
|
|
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart,
|
|
SRCCOPY);
|
|
|
|
// Mask out the places where the bitmap will be placed.
|
|
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
|
|
|
|
// Mask out the transparent colored pixels on the bitmap.
|
|
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
|
|
|
|
// XOR the bitmap with the background on the destination DC.
|
|
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
|
|
|
|
// Copy the destination to the screen.
|
|
BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0,
|
|
SRCCOPY);
|
|
|
|
// Place the original bitmap back into the bitmap sent here.
|
|
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
|
|
|
|
// Delete the memory bitmaps.
|
|
DeleteObject(SelectObject(hdcBack, bmBackOld));
|
|
DeleteObject(SelectObject(hdcObject, bmObjectOld));
|
|
DeleteObject(SelectObject(hdcMem, bmMemOld));
|
|
DeleteObject(SelectObject(hdcSave, bmSaveOld));
|
|
|
|
// Delete the memory DCs.
|
|
DeleteDC(hdcMem);
|
|
DeleteDC(hdcBack);
|
|
DeleteDC(hdcObject);
|
|
DeleteDC(hdcSave);
|
|
DeleteDC(hdcTemp);
|
|
}
|
|
|
|
//
|
|
// Handler for WM_DRAWITEM (see platform sdk)
|
|
// Handles owner draw items
|
|
//
|
|
//
|
|
VOID
|
|
CAutoReconnectDlg::OnDrawItem(
|
|
HWND hwnd,
|
|
const DRAWITEMSTRUCT *pDIS
|
|
)
|
|
{
|
|
DC_BEGIN_FN("OnDrawItem");
|
|
|
|
HPALETTE hPaletteOld = NULL;
|
|
HFONT hfntSelected;
|
|
int iBkMode;
|
|
COLORREF colorText;
|
|
RECT rc;
|
|
SIZE size;
|
|
TCHAR szText[256];
|
|
|
|
|
|
hPaletteOld = SelectPalette(pDIS->hDC, _hPalette, FALSE);
|
|
(UINT)RealizePalette(pDIS->hDC);
|
|
switch (pDIS->CtlID)
|
|
{
|
|
case IDC_TITLE_ARCING:
|
|
{
|
|
// Draw the title of the dialog "AutoReconecting".
|
|
hfntSelected = static_cast<HFONT>(SelectObject(pDIS->hDC,
|
|
_hfntTitle));
|
|
colorText = SetTextColor(pDIS->hDC, 0x00FFFFFF);
|
|
iBkMode = SetBkMode(pDIS->hDC, TRANSPARENT);
|
|
(int)GetWindowText(GetDlgItem(hwnd, pDIS->CtlID),
|
|
szText,
|
|
sizeof(szText)/sizeof(szText[0]));
|
|
GetTextExtentPoint(pDIS->hDC, szText, lstrlen(szText), &size);
|
|
CopyRect(&rc, &pDIS->rcItem);
|
|
InflateRect(&rc, 0, -((rc.bottom - rc.top - size.cy) / 2));
|
|
DrawText(pDIS->hDC, szText, -1, &rc, 0);
|
|
SetBkMode(pDIS->hDC, iBkMode);
|
|
SetTextColor(pDIS->hDC, colorText);
|
|
SelectObject(pDIS->hDC, hfntSelected);
|
|
}
|
|
break;
|
|
|
|
case IDC_TITLE_FLAG:
|
|
{
|
|
BITMAP bitmap;
|
|
|
|
GetClientRect(pDIS->hwndItem, &rc);
|
|
if (GetObject(_hbmFlag, sizeof(bitmap), &bitmap) != 0)
|
|
{
|
|
rc.left += ((rc.right - rc.left) - bitmap.bmWidth) / 2;
|
|
rc.right = rc.left + bitmap.bmWidth;
|
|
rc.top += ((rc.bottom - rc.top) - bitmap.bmHeight) / 2;
|
|
rc.bottom = rc.top + bitmap.bmHeight;
|
|
}
|
|
PaintBitmap(pDIS->hDC, &rc, _hbmFlag, &_rcFlag);
|
|
}
|
|
break;
|
|
case IDC_ARC_STATIC_DISCBMP:
|
|
{
|
|
xDrawTransparentBitmap(pDIS->hDC, _hbmDisconImg,
|
|
0, 0,
|
|
TRANSPARENT_MASK_COLOR);
|
|
}
|
|
break;
|
|
}
|
|
(HGDIOBJ)SelectPalette(pDIS->hDC, hPaletteOld, FALSE);
|
|
(UINT)RealizePalette(pDIS->hDC);
|
|
|
|
|
|
DC_END_FN();
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// StaticDialogBoxProc
|
|
// Params: see platform sdk for wndproc
|
|
//
|
|
// Delegates work to appropriate instance
|
|
//
|
|
//
|
|
INT_PTR CALLBACK
|
|
CAutoReconnectDlg::StaticDialogBoxProc(
|
|
HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
//
|
|
// Delegate to appropriate instance
|
|
// (only works for single instance dialogs)
|
|
//
|
|
DC_BEGIN_FN("StaticDialogBoxProc");
|
|
DCINT retVal = 0;
|
|
CAutoReconnectDlg* pDlg;
|
|
|
|
if(WM_INITDIALOG != uMsg) {
|
|
//
|
|
// Need to retreive the instance pointer from the window class
|
|
//
|
|
pDlg = (CAutoReconnectDlg*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
|
}
|
|
else {
|
|
//
|
|
// WM_INITDIALOG need to grab and set instance pointer
|
|
//
|
|
|
|
//
|
|
// lParam contains this pointer (passed in DialogBoxParam)
|
|
//
|
|
pDlg = (CAutoReconnectDlg*) lParam;
|
|
TRC_ASSERT(pDlg,(TB,_T("Got null instance pointer (lParam) in WM_INITDIALOG")));
|
|
if(!pDlg) {
|
|
DC_QUIT;
|
|
}
|
|
//
|
|
// Store the dialog pointer in the windowclass
|
|
//
|
|
SetLastError(0);
|
|
if(!SetWindowLongPtr( hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlg)) {
|
|
if(GetLastError()) {
|
|
TRC_ERR((TB,_T("SetWindowLongPtr failed 0x%x"),
|
|
GetLastError()));
|
|
DC_QUIT;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pDlg) {
|
|
retVal = pDlg->DialogBoxProc(hwndDlg, uMsg, wParam, lParam);
|
|
}
|
|
|
|
DC_EXIT_POINT:
|
|
DC_END_FN();
|
|
return retVal;
|
|
}
|
|
|
|
|
|
//
|
|
// Name: DialogBoxProc
|
|
//
|
|
// Purpose: Handles AutoReconnect dialog box proc
|
|
//
|
|
// Returns: TRUE if message dealt with
|
|
// FALSE otherwise
|
|
//
|
|
// Params: See windows documentation
|
|
//
|
|
//
|
|
INT_PTR CALLBACK CAutoReconnectDlg::DialogBoxProc (HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
INT_PTR rc = FALSE;
|
|
DC_BEGIN_FN("DialogBoxProc");
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
//
|
|
// Center
|
|
//
|
|
_hwnd = hwndDlg;
|
|
CenterWindow(_hwndOwner, 2, 2);
|
|
UpdateConnectionAttempts(0, 0);
|
|
|
|
//
|
|
// The band is positioned a fixed ratio of the way
|
|
// down the height of this dialog to match up with the
|
|
// background image
|
|
//
|
|
RECT cliRect;
|
|
LONG nBandPos = 0;
|
|
GetClientRect(hwndDlg, &cliRect);
|
|
nBandPos = (INT)((cliRect.bottom - cliRect.top) * 42.0/193.0);
|
|
|
|
_pProgBand = new CProgressBand(hwndDlg,
|
|
_hInstance,
|
|
nBandPos,
|
|
IDB_ARC_BAND24,
|
|
IDB_ARC_BAND8,
|
|
NULL);
|
|
if (_pProgBand) {
|
|
if (!_pProgBand->Initialize()) {
|
|
TRC_ERR((TB,_T("Progress band failed to init")));
|
|
delete _pProgBand;
|
|
_pProgBand = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Subclass the cancel button to do the correct key handling
|
|
// this is important because the message loop is driven by
|
|
// the container application so we can't just rely on it
|
|
// calling IsDialogMessage(). In other words we need to manually
|
|
// handle the appropriate keymapping code.
|
|
//
|
|
#ifndef OS_WINCE
|
|
if (!SetWindowSubclass(GetDlgItem(hwndDlg, IDCANCEL),
|
|
CancelBtnSubclassProc, IDCANCEL,
|
|
reinterpret_cast<DWORD_PTR>(this))) {
|
|
|
|
TRC_ERR((TB,_T("SetWindowSubclass failed: 0x%x"),
|
|
GetLastError()));
|
|
|
|
}
|
|
#else
|
|
_lOldCancelProc = (WNDPROC )SetWindowLong(GetDlgItem(hwndDlg, IDCANCEL),
|
|
GWL_WNDPROC, (LONG )CancelBtnSubclassProc);
|
|
SetWindowLong(GetDlgItem(hwndDlg, IDCANCEL), GWL_USERDATA, reinterpret_cast<DWORD_PTR>(this));
|
|
#endif
|
|
//
|
|
// Set the focus on the cancel button
|
|
// and make it the default button
|
|
//
|
|
SendMessage(hwndDlg, DM_SETDEFID, IDCANCEL, 0);
|
|
|
|
//SetFocus(GetDlgItem(hwndDlg, IDCANCEL));
|
|
SetFocus(hwndDlg);
|
|
|
|
if (_pProgBand) {
|
|
_pProgBand->StartSpinning();
|
|
}
|
|
|
|
rc = 1;
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
switch(DC_GET_WM_COMMAND_ID(wParam))
|
|
{
|
|
case IDCANCEL:
|
|
{
|
|
TRC_NRM((TB,_T("AutoReconnect cancel was pressed")));
|
|
|
|
if (_pProgBand) {
|
|
_pProgBand->StopSpinning();
|
|
}
|
|
|
|
_pUi->UI_UserInitiatedDisconnect(_lastDiscReason);
|
|
|
|
//
|
|
// Disable the cancel button and set the cancel flag.
|
|
// This will take effect on the next autoreconnection
|
|
// notification.
|
|
//
|
|
EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
|
|
_fContinueReconAttempts = FALSE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break; //WM_COMMAND
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
ARC_DBG_SETINFO(ARCDLG_DEBUG_WMDESTROYCALLED);
|
|
#ifndef OS_WINCE
|
|
RemoveWindowSubclass(GetDlgItem(hwndDlg, IDCANCEL),
|
|
CancelBtnSubclassProc, IDCANCEL);
|
|
#else
|
|
SetWindowLong(GetDlgItem(hwndDlg, IDCANCEL),
|
|
GWL_WNDPROC, (LONG )_lOldCancelProc);
|
|
#endif
|
|
//
|
|
// Clear the instance data to prevent further processing
|
|
// after the dialog is deleted
|
|
//
|
|
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)NULL);
|
|
}
|
|
break;
|
|
|
|
#ifndef OS_WINCE
|
|
case WM_DRAWITEM:
|
|
{
|
|
OnDrawItem(hwndDlg, (DRAWITEMSTRUCT*)(lParam));
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
case WM_TIMER:
|
|
{
|
|
if (_pProgBand) {
|
|
_pProgBand->OnTimer((INT)wParam);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_ERASEBKGND:
|
|
{
|
|
OnEraseBkgnd(hwndDlg, (HDC)wParam);
|
|
|
|
if (_pProgBand) {
|
|
_pProgBand->OnEraseParentBackground((HDC)wParam);
|
|
}
|
|
rc = 1;
|
|
}
|
|
break;
|
|
|
|
case WM_CTLCOLORDLG:
|
|
{
|
|
SetBkMode((HDC)wParam, TRANSPARENT);
|
|
rc = (INT_PTR)GetStockObject(NULL_BRUSH);
|
|
}
|
|
break;
|
|
|
|
case WM_CTLCOLORSTATIC:
|
|
{
|
|
SetTextColor((HDC)wParam, RGB(255,255,255));
|
|
SetBkMode((HDC)wParam, TRANSPARENT);
|
|
#ifndef OS_WINCE
|
|
rc = (INT_PTR)GetStockObject(NULL_BRUSH);
|
|
#else
|
|
LONG lId = GetWindowLong((HWND)lParam, GWL_ID);
|
|
rc = (INT_PTR)((lId == IDC_TITLE_ARCING) ? _hbrTopBand : _hbrMidBand);
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
#ifndef OS_WINCE
|
|
case WM_PRINTCLIENT:
|
|
{
|
|
OnPrintClient(hwndDlg, (HDC)wParam, (DWORD)lParam);
|
|
rc = 1;
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
{
|
|
rc = 0;
|
|
}
|
|
break;
|
|
}
|
|
|
|
DC_END_FN();
|
|
|
|
return(rc);
|
|
|
|
} /* DialogBoxProc */
|
|
|
|
VOID CAutoReconnectDlg::UpdateConnectionAttempts(
|
|
ULONG conAttempts,
|
|
ULONG maxConAttempts)
|
|
{
|
|
LPTSTR szFormattedString = NULL;
|
|
HWND hwndStatic;
|
|
|
|
DC_BEGIN_FN("UpdateConnectionAttempts");
|
|
|
|
hwndStatic = GetDlgItem(GetHwnd(), IDC_ARC_STATIC_INFO);
|
|
|
|
szFormattedString = FormatMessageVArgs(
|
|
_szConnectAttemptStringTmpl,
|
|
conAttempts,
|
|
maxConAttempts
|
|
);
|
|
|
|
if (szFormattedString) {
|
|
SetDlgItemText(GetHwnd(),
|
|
IDC_ARC_STATIC_INFO,
|
|
szFormattedString);
|
|
LocalFree(szFormattedString);
|
|
|
|
//
|
|
// Invalidate the static control to trigger a repaint
|
|
//
|
|
if (hwndStatic) {
|
|
RECT rc;
|
|
if (GetWindowRect(hwndStatic, &rc)) {
|
|
MapWindowPoints(HWND_DESKTOP, GetHwnd(),
|
|
(LPPOINT)&rc,sizeof(RECT)/sizeof(POINT));
|
|
InvalidateRect(GetHwnd(), &rc, TRUE);
|
|
UpdateWindow(GetHwnd());
|
|
}
|
|
}
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
//
|
|
// Called to notify us that we got disconnected
|
|
// this means the last connection attempt failed
|
|
//
|
|
// Params:
|
|
// discReason - disconnect major reason code
|
|
// attemptCount - attempt count so far
|
|
// pfContinueArc - [OUT] set to FALSE to stop ARC
|
|
//
|
|
VOID
|
|
CAutoReconnectDlg::OnNotifyAutoReconnecting(
|
|
UINT discReason,
|
|
ULONG attemptCount,
|
|
ULONG maxAttemptCount,
|
|
BOOL* pfContinueArc
|
|
)
|
|
{
|
|
DC_BEGIN_FN("OnNotifyDisconnected");
|
|
|
|
_lastDiscReason = discReason;
|
|
|
|
if (_fContinueReconAttempts) {
|
|
_connectionAttempts = attemptCount;
|
|
UpdateConnectionAttempts(attemptCount, maxAttemptCount);
|
|
}
|
|
else {
|
|
TRC_NRM((TB,_T("Stopping arc - _fContinueReconAttempts is FALSE")));
|
|
}
|
|
|
|
*pfContinueArc = _fContinueReconAttempts;
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
//
|
|
// Called to notify us that we have connected
|
|
//
|
|
VOID CAutoReconnectDlg::OnNotifyConnected()
|
|
{
|
|
DC_BEGIN_FN("OnNotifyConnected");
|
|
|
|
_fContinueReconAttempts = FALSE;
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
//
|
|
// Destory
|
|
// Called to kill and cleanup the dialog
|
|
//
|
|
//
|
|
BOOL
|
|
CAutoReconnectDlg::Destroy()
|
|
{
|
|
DC_BEGIN_FN("Destroy");
|
|
|
|
ARC_DBG_SETINFO(ARCDLG_DEBUG_DESTROYCALLED);
|
|
|
|
if (!DestroyWindow(_hwnd)) {
|
|
TRC_ERR((TB,_T("DestroyWindow failed: 0x%x"),
|
|
GetLastError()));
|
|
}
|
|
else {
|
|
ARC_DBG_SETINFO(ARCDLG_DEBUG_WMDESTROYSUCCEED);
|
|
}
|
|
|
|
//
|
|
// Clear the instance data to prevent further processing
|
|
// after the dialog is deleted
|
|
//
|
|
ARC_DBG_SETINFO(ARCDLG_DEBUG_SETNULLINSTPTR);
|
|
|
|
SetWindowLongPtr(_hwnd, GWLP_USERDATA, (LONG_PTR)NULL);
|
|
|
|
DC_END_FN();
|
|
return TRUE;
|
|
}
|
|
|
|
#ifndef OS_WINCE
|
|
LRESULT CALLBACK
|
|
CAutoReconnectDlg::CancelBtnSubclassProc(
|
|
HWND hwnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
UINT_PTR uiID,
|
|
DWORD_PTR dwRefData
|
|
)
|
|
#else
|
|
LRESULT CALLBACK
|
|
CAutoReconnectDlg::CancelBtnSubclassProc(
|
|
HWND hwnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
#endif
|
|
{
|
|
LRESULT rc = 0;
|
|
CAutoReconnectDlg* pThis = NULL;
|
|
|
|
DC_BEGIN_FN("CancelBtnSubclassProc");
|
|
|
|
#ifndef OS_WINCE
|
|
pThis = reinterpret_cast<CAutoReconnectDlg*>(dwRefData);
|
|
#else
|
|
pThis = reinterpret_cast<CAutoReconnectDlg*>(GetWindowLong(hwnd, GWL_USERDATA));
|
|
#endif
|
|
TRC_ASSERT(pThis, (TB,_T("pThis == NULL")));
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_KEYUP:
|
|
{
|
|
//
|
|
// Hitting 'Esc' or 'Return' on the Cancel button
|
|
// are the same as pressing it
|
|
//
|
|
if (VK_ESCAPE == wParam ||
|
|
VK_RETURN == wParam) {
|
|
SendMessage(hwnd, BM_CLICK, NULL, NULL);
|
|
}
|
|
}
|
|
//
|
|
// Intentional fallthru
|
|
//
|
|
|
|
default:
|
|
{
|
|
#ifndef OS_WINCE
|
|
rc = DefSubclassProc(hwnd, uMsg, wParam, lParam);
|
|
#else
|
|
rc = CallWindowProc(pThis->_lOldCancelProc, hwnd, uMsg, wParam, lParam);
|
|
#endif
|
|
}
|
|
break;
|
|
}
|
|
|
|
DC_END_FN();
|
|
return rc;
|
|
}
|
|
|
|
#else // ARC_MINIMAL_UI
|
|
|
|
#include "res_inc.c"
|
|
|
|
CAutoReconnectPlainUI::CAutoReconnectPlainUI(HWND hwndOwner,
|
|
HINSTANCE hInst,
|
|
CUI* pUi) :
|
|
CAutoReconnectUI(hwndOwner, hInst, pUi),
|
|
_fInitialized(FALSE),
|
|
_hPalette(NULL),
|
|
_fIsUiVisible(FALSE)
|
|
{
|
|
#ifndef OS_WINCE
|
|
BOOL fUse8BitDepth = FALSE;
|
|
#else
|
|
BOOL fUse8BitDepth = TRUE;
|
|
#endif
|
|
LOGFONT logFont;
|
|
#ifndef OS_WINCE
|
|
HDC hdcScreen;
|
|
#else
|
|
#endif
|
|
BITMAP bitmap;
|
|
INT logPixelsY = 100;
|
|
|
|
DC_BEGIN_FN("CAutoReconnectPlainUI");
|
|
|
|
_nFlashingTimer = 0;
|
|
_fContinueReconAttempts = TRUE;
|
|
|
|
#ifndef OS_WINCE
|
|
//
|
|
// Get color depth
|
|
//
|
|
hdcScreen = GetDC(NULL);
|
|
if (hdcScreen) {
|
|
fUse8BitDepth = (GetDeviceCaps(hdcScreen, BITSPIXEL) <= 8);
|
|
logPixelsY = GetDeviceCaps(hdcScreen, LOGPIXELSY);
|
|
|
|
//
|
|
// Load bitmaps
|
|
//
|
|
LPBYTE pBitmapBits = fUse8BitDepth ? (LPBYTE)g_DisconImage8Bits :
|
|
(LPBYTE)g_DisconImageBits;
|
|
ULONG cbBitmapLen = fUse8BitDepth ? g_cbDisconImage8Bits :
|
|
g_cbDisconImageBits;
|
|
|
|
_hbmDisconImg = (HBITMAP)LoadImageFromMemory(
|
|
hdcScreen,
|
|
(LPBYTE)pBitmapBits,
|
|
cbBitmapLen
|
|
);
|
|
if ((_hbmDisconImg != NULL) &&
|
|
(GetObject(_hbmDisconImg,
|
|
sizeof(bitmap), &bitmap) >= sizeof(bitmap))) {
|
|
SetRect(&_rcDisconImg, 0, 0, bitmap.bmWidth, bitmap.bmHeight);
|
|
|
|
_hPalette = CUT::UT_GetPaletteForBitmap(NULL, _hbmDisconImg);
|
|
}
|
|
ReleaseDC(NULL, hdcScreen);
|
|
hdcScreen = NULL;
|
|
}
|
|
|
|
#endif
|
|
|
|
_fInitialized = (_hbmDisconImg && _pUi);
|
|
if (!_fInitialized) {
|
|
TRC_ERR((TB,_T("Failed to properly init arc dlg")));
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
CAutoReconnectPlainUI::~CAutoReconnectPlainUI()
|
|
{
|
|
#ifndef OS_WINCE
|
|
if (_hbmDisconImg) {
|
|
DeleteObject(_hbmDisconImg);
|
|
_hbmDisconImg = NULL;
|
|
}
|
|
#endif
|
|
|
|
if (_hPalette) {
|
|
DeleteObject(_hPalette);
|
|
_hPalette = NULL;
|
|
}
|
|
}
|
|
|
|
#define ARC_PLAIN_WNDCLASS _T("ARCICON")
|
|
HWND CAutoReconnectPlainUI::StartModeless()
|
|
{
|
|
LONG_PTR dwStyle;
|
|
WNDCLASS tmpWndClass;
|
|
WNDCLASS plainArcWndClass;
|
|
ATOM registerClassRc;
|
|
|
|
DC_BEGIN_FN("StartModeless");
|
|
|
|
if (!_fInitialized) {
|
|
TRC_ERR((TB,_T("failing startmodeless fInitialized is FALSE")));
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Create a window to host the UI
|
|
//
|
|
//
|
|
// Register the class for the Main Window
|
|
//
|
|
if (!GetClassInfo(_hInstance, ARC_PLAIN_WNDCLASS, &tmpWndClass))
|
|
{
|
|
TRC_NRM((TB, _T("Register Main Window class")));
|
|
plainArcWndClass.style = CS_DBLCLKS;
|
|
plainArcWndClass.lpfnWndProc = StaticPlainArcWndProc;
|
|
plainArcWndClass.cbClsExtra = 0;
|
|
plainArcWndClass.cbWndExtra = sizeof(void*); //store 'this' pointer
|
|
plainArcWndClass.hInstance = _hInstance;
|
|
plainArcWndClass.hIcon = NULL;
|
|
plainArcWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
plainArcWndClass.hbrBackground = (HBRUSH) GetStockObject(HOLLOW_BRUSH);
|
|
plainArcWndClass.lpszMenuName = NULL;
|
|
plainArcWndClass.lpszClassName = ARC_PLAIN_WNDCLASS;
|
|
|
|
registerClassRc = RegisterClass (&plainArcWndClass);
|
|
|
|
if (registerClassRc == 0)
|
|
{
|
|
TRC_ERR((TB,_T("RegisterClass failed: 0x%x"), GetLastError()));
|
|
DC_QUIT;
|
|
}
|
|
}
|
|
|
|
_hwnd = CreateWindow(ARC_PLAIN_WNDCLASS,
|
|
NULL,
|
|
WS_CHILD | WS_CLIPSIBLINGS,
|
|
0,
|
|
0,
|
|
_rcDisconImg.right - _rcDisconImg.left,
|
|
_rcDisconImg.bottom - _rcDisconImg.top,
|
|
_hwndOwner,
|
|
NULL,
|
|
_hInstance,
|
|
this
|
|
);
|
|
|
|
if (_hwnd) {
|
|
//
|
|
// Move window to the parent's top-right and then show the window
|
|
//
|
|
MoveToParentTopRight();
|
|
ShowTopMost();
|
|
_fIsUiVisible = TRUE;
|
|
}
|
|
else {
|
|
TRC_ERR((TB,_T("CreateWindow failed: 0x%x"), GetLastError()));
|
|
}
|
|
|
|
DC_EXIT_POINT:
|
|
DC_END_FN();
|
|
return _hwnd;
|
|
}
|
|
|
|
BOOL CAutoReconnectPlainUI::ShowTopMost()
|
|
{
|
|
BOOL rc = FALSE;
|
|
DC_BEGIN_FN("ShowTopMost");
|
|
|
|
if (!_hwnd) {
|
|
DC_QUIT;
|
|
}
|
|
|
|
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
|
|
|
//
|
|
// Bring the window to the TOP of the Z order
|
|
//
|
|
SetWindowPos( _hwnd,
|
|
HWND_TOPMOST,
|
|
0, 0, 0, 0,
|
|
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
|
|
|
|
rc = TRUE;
|
|
|
|
DC_EXIT_POINT:
|
|
DC_END_FN();
|
|
return rc;
|
|
}
|
|
|
|
//
|
|
// Position offset from the edge
|
|
//
|
|
#define ICON_POSITION_OFFSET 20
|
|
|
|
VOID
|
|
CAutoReconnectPlainUI::MoveToParentTopRight()
|
|
{
|
|
RECT rcParent;
|
|
INT xPos, yPos;
|
|
DC_BEGIN_FN("OnParentSizePosChange");
|
|
|
|
//
|
|
// Reposition the dialog to the top right
|
|
// of the owner window
|
|
//
|
|
if (_hwnd && _hwndOwner) {
|
|
//
|
|
// Position the window in the top-right of the parent
|
|
//
|
|
GetClientRect(_hwndOwner, &rcParent);
|
|
xPos = rcParent.right - ICON_POSITION_OFFSET -
|
|
(_rcDisconImg.right - _rcDisconImg.left);
|
|
yPos = rcParent.top + ICON_POSITION_OFFSET;
|
|
|
|
SetWindowPos(_hwnd,
|
|
NULL,
|
|
xPos, yPos,
|
|
0, 0,
|
|
SWP_NOSIZE | SWP_NOACTIVATE);
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
VOID
|
|
CAutoReconnectPlainUI::OnParentSizePosChange()
|
|
{
|
|
MoveToParentTopRight();
|
|
}
|
|
|
|
//
|
|
// Handler for WM_ERASEBKGND (See platform sdk docs)
|
|
//
|
|
VOID
|
|
CAutoReconnectPlainUI::OnEraseBkgnd(
|
|
HWND hwnd,
|
|
HDC hdc
|
|
)
|
|
{
|
|
RECT rc;
|
|
HPALETTE hPaletteOld = NULL;
|
|
DC_BEGIN_FN("OnEraseBkgnd");
|
|
|
|
TRC_ASSERT(_hbmDisconImg, (TB,_T("_hbmBackground is NULL")));
|
|
|
|
if (GetClientRect(hwnd, &rc)) {
|
|
|
|
hPaletteOld = SelectPalette(hdc, _hPalette, FALSE);
|
|
RealizePalette(hdc);
|
|
|
|
PaintBitmap(hdc, &rc, _hbmDisconImg, &_rcDisconImg);
|
|
|
|
SelectPalette(hdc, hPaletteOld, FALSE);
|
|
RealizePalette(hdc);
|
|
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
|
|
//
|
|
// Handler for WM_PRINTCLIENT
|
|
//
|
|
VOID
|
|
CAutoReconnectPlainUI::OnPrintClient(
|
|
HWND hwnd,
|
|
HDC hdcPrint,
|
|
DWORD dwOptions)
|
|
{
|
|
DC_BEGIN_FN("OnPrintClient");
|
|
|
|
#ifndef OS_WINCE
|
|
if ((dwOptions & (PRF_ERASEBKGND | PRF_CLIENT)) != 0)
|
|
{
|
|
OnEraseBkgnd(hwnd, hdcPrint);
|
|
}
|
|
#endif
|
|
DC_END_FN();
|
|
}
|
|
|
|
//
|
|
// StaticPlainArcWndProc
|
|
// Params: see platform sdk for wndproc
|
|
//
|
|
// Delegates work to appropriate instance
|
|
//
|
|
//
|
|
LRESULT CALLBACK
|
|
CAutoReconnectPlainUI::StaticPlainArcWndProc(
|
|
HWND hwnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
INT retVal = 0;
|
|
CAutoReconnectPlainUI* pUI;
|
|
|
|
DC_BEGIN_FN("StaticPlainArcWndProc");
|
|
|
|
pUI = (CAutoReconnectPlainUI*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
if(WM_CREATE == uMsg)
|
|
{
|
|
//pull out the this pointer and stuff it in the window class
|
|
LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
|
|
pUI = (CAutoReconnectPlainUI*)lpcs->lpCreateParams;
|
|
|
|
SetWindowLongPtr( hwnd, GWLP_USERDATA, (LONG_PTR)pUI);
|
|
}
|
|
|
|
//
|
|
// Delegate the message to the appropriate instance
|
|
//
|
|
|
|
if(pUI) {
|
|
return pUI->WndProc(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
else {
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
DC_EXIT_POINT:
|
|
DC_END_FN();
|
|
return retVal;
|
|
}
|
|
|
|
#define ARC_PLAIN_UI_TIMERID 1
|
|
#define ARC_ANIM_TIME 400
|
|
//
|
|
// Name: WndProc
|
|
//
|
|
// Purpose: Handles AutoReconnect dialog box proc
|
|
//
|
|
// Returns: TRUE if message dealt with
|
|
// FALSE otherwise
|
|
//
|
|
// Params: See windows documentation
|
|
//
|
|
//
|
|
LRESULT CALLBACK CAutoReconnectPlainUI::WndProc(HWND hwnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
INT_PTR rc = FALSE;
|
|
DC_BEGIN_FN("DialogBoxProc");
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_CREATE:
|
|
{
|
|
_nFlashingTimer = SetTimer(hwnd, ARC_PLAIN_UI_TIMERID,
|
|
ARC_ANIM_TIME,
|
|
NULL
|
|
);
|
|
if (_nFlashingTimer) {
|
|
SetFocus(hwnd);
|
|
}
|
|
else {
|
|
TRC_ERR((TB,_T("SetTimer failed - 0x%x"),
|
|
GetLastError()));
|
|
rc = -1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
if (_nFlashingTimer) {
|
|
KillTimer(hwnd, _nFlashingTimer);
|
|
_nFlashingTimer = 0;
|
|
}
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)NULL);
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_TIMER:
|
|
{
|
|
//
|
|
// DO animation stuff
|
|
//
|
|
OnAnimFlashTimer();
|
|
}
|
|
break;
|
|
|
|
case WM_ERASEBKGND:
|
|
{
|
|
OnEraseBkgnd(hwnd, (HDC)wParam);
|
|
rc = 1;
|
|
}
|
|
break;
|
|
|
|
case WM_KEYUP:
|
|
{
|
|
if (VK_ESCAPE == wParam) {
|
|
TRC_NRM((TB,_T("ARC ESC pressed, disconnect")));
|
|
_pUi->UI_UserInitiatedDisconnect(_lastDiscReason);
|
|
_fContinueReconAttempts = FALSE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
{
|
|
TRC_NRM((TB,_T("Setfocus to arc")));
|
|
}
|
|
break;
|
|
|
|
case WM_KILLFOCUS:
|
|
{
|
|
TRC_NRM((TB,_T("killfocus to arc: 0x%x 0x%x"), wParam, lParam));
|
|
}
|
|
break;
|
|
|
|
|
|
#ifndef OS_WINCE
|
|
case WM_PRINTCLIENT:
|
|
{
|
|
OnPrintClient(hwnd, (HDC)wParam, (DWORD)lParam);
|
|
rc = 1;
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
{
|
|
return DefWindowProc( hwnd, uMsg, wParam, lParam);
|
|
}
|
|
break;
|
|
}
|
|
|
|
DC_END_FN();
|
|
|
|
return(rc);
|
|
|
|
} /* DialogBoxProc */
|
|
|
|
|
|
VOID
|
|
CAutoReconnectPlainUI::OnAnimFlashTimer()
|
|
{
|
|
//
|
|
// Toggle UI hide state
|
|
//
|
|
_fIsUiVisible = !_fIsUiVisible;
|
|
ShowWindow(_hwnd, _fIsUiVisible ? SW_SHOWNORMAL : SW_HIDE);
|
|
}
|
|
|
|
//
|
|
// Called to notify us that we got disconnected
|
|
// this means the last connection attempt failed
|
|
//
|
|
// Params:
|
|
// discReason - disconnect major reason code
|
|
// attemptCount - attempt count so far
|
|
// pfContinueArc - [OUT] set to FALSE to stop ARC
|
|
//
|
|
VOID
|
|
CAutoReconnectPlainUI::OnNotifyAutoReconnecting(
|
|
UINT discReason,
|
|
ULONG attemptCount,
|
|
ULONG maxAttemptCount,
|
|
BOOL* pfContinueArc
|
|
)
|
|
{
|
|
DC_BEGIN_FN("OnNotifyDisconnected");
|
|
|
|
_lastDiscReason = discReason;
|
|
|
|
if (!_fContinueReconAttempts) {
|
|
TRC_NRM((TB,_T("Stopping arc - _fContinueReconAttempts is FALSE")));
|
|
}
|
|
|
|
*pfContinueArc = _fContinueReconAttempts;
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
//
|
|
// Called to notify us that we have connected
|
|
//
|
|
VOID CAutoReconnectPlainUI::OnNotifyConnected()
|
|
{
|
|
DC_BEGIN_FN("OnNotifyConnected");
|
|
|
|
_fContinueReconAttempts = FALSE;
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
//
|
|
// Destory
|
|
// Called to kill and cleanup the dialog
|
|
//
|
|
//
|
|
BOOL
|
|
CAutoReconnectPlainUI::Destroy()
|
|
{
|
|
DC_BEGIN_FN("Destroy");
|
|
|
|
if (!DestroyWindow(_hwnd)) {
|
|
TRC_ERR((TB,_T("DestroyWindow failed: 0x%x"),
|
|
GetLastError()));
|
|
}
|
|
|
|
DC_END_FN();
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Load a bitmap from memory
|
|
//
|
|
// Params:
|
|
// pbBitmapBits - pointer to bitmap bits (e.g. can pass in file mapping
|
|
// to a BMP file).
|
|
//
|
|
// cbLen - length of pbBitmapBits
|
|
//
|
|
// Returns:
|
|
// HBITMAP - handle to the bitmap
|
|
//
|
|
HBITMAP
|
|
CAutoReconnectPlainUI::LoadImageFromMemory(
|
|
HDC hdc,
|
|
LPBYTE pbBitmapBits,
|
|
ULONG cbLen
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
HBITMAP hbmp = NULL;
|
|
LPBITMAPINFO pbmi = NULL;
|
|
ULONG cbBmiLen = 0;
|
|
PBYTE pBitmapBits = NULL;
|
|
ULONG cbBitmapBits = 0;
|
|
|
|
hr = LoadImageBits(
|
|
pbBitmapBits,
|
|
cbLen,
|
|
&pbmi,
|
|
&cbBmiLen,
|
|
&pBitmapBits,
|
|
&cbBitmapBits
|
|
);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
hbmp = CreateDIBitmap(hdc,
|
|
&pbmi->bmiHeader,
|
|
CBM_INIT,
|
|
pBitmapBits,
|
|
pbmi,
|
|
DIB_RGB_COLORS
|
|
);
|
|
|
|
delete pBitmapBits;
|
|
delete pbmi;
|
|
}
|
|
|
|
return hbmp;
|
|
}
|
|
|
|
|
|
#define BMP_24_BITSPERPIXEL 24
|
|
#define BMP_16_BITSPERPIXEL 16
|
|
#define BMP_32_BITSPERPIXEL 32
|
|
|
|
//
|
|
// Worker function for image load, caller frees outparam bits
|
|
//
|
|
HRESULT
|
|
CAutoReconnectPlainUI::LoadImageBits(
|
|
LPBYTE pbBitmapBits, ULONG cbLen,
|
|
LPBITMAPINFO* ppBitmapInfo, PULONG pcbBitmapInfo,
|
|
LPBYTE* ppBits, PULONG pcbBits
|
|
)
|
|
{
|
|
HRESULT hr = ResultFromScode(S_OK);
|
|
BITMAPFILEHEADER bmfh;
|
|
BITMAPCOREHEADER *pbch;
|
|
BITMAPINFOHEADER bih;
|
|
LPBYTE pbStart;
|
|
ULONG cbi = 0;
|
|
ULONG cbData;
|
|
LPBITMAPINFO pbi = NULL;
|
|
LPBYTE pbData = NULL;
|
|
DWORD dwSizeOfHeader;
|
|
|
|
//
|
|
// Record the starting position
|
|
//
|
|
|
|
pbStart = pbBitmapBits;
|
|
|
|
//
|
|
// First validate the buffer for size
|
|
//
|
|
|
|
if (cbLen < sizeof(BITMAPFILEHEADER))
|
|
{
|
|
return(ResultFromScode(E_FAIL));
|
|
}
|
|
|
|
//
|
|
// Now get the bitmap file header
|
|
//
|
|
memcpy(&bmfh, pbBitmapBits, sizeof(BITMAPFILEHEADER));
|
|
|
|
//
|
|
// Validate the header
|
|
//
|
|
|
|
if (!(bmfh.bfType == 0x4d42) && (bmfh.bfOffBits <= cbLen))
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// Get the next 4 bytes which will represent the size of the
|
|
// next structure and allow us to determine the type
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pbBitmapBits += sizeof(BITMAPFILEHEADER);
|
|
memcpy(&dwSizeOfHeader, pbBitmapBits, sizeof(DWORD));
|
|
|
|
if (dwSizeOfHeader == sizeof(BITMAPCOREHEADER))
|
|
{
|
|
pbch = (BITMAPCOREHEADER *)pbBitmapBits;
|
|
memset(&bih, 0, sizeof(BITMAPINFOHEADER));
|
|
|
|
bih.biSize = sizeof(BITMAPINFOHEADER);
|
|
bih.biWidth = pbch->bcWidth;
|
|
bih.biHeight = pbch->bcHeight;
|
|
bih.biPlanes = pbch->bcPlanes;
|
|
bih.biBitCount = pbch->bcBitCount;
|
|
|
|
pbBitmapBits += sizeof(BITMAPCOREHEADER);
|
|
}
|
|
else if (dwSizeOfHeader == sizeof(BITMAPINFOHEADER))
|
|
{
|
|
memcpy(&bih, pbBitmapBits, sizeof(BITMAPINFOHEADER));
|
|
|
|
pbBitmapBits += sizeof(BITMAPINFOHEADER);
|
|
}
|
|
else
|
|
{
|
|
hr = ResultFromScode(E_FAIL);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check if biClrUsed is set since we do not handle that
|
|
// case at this time
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (bih.biClrUsed != 0)
|
|
{
|
|
hr = ResultFromScode(E_FAIL);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now we need to calculate the size of the BITMAPINFO we need
|
|
// to allocate including any palette information
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// First the size of the header
|
|
//
|
|
|
|
cbi = sizeof(BITMAPINFOHEADER);
|
|
|
|
//
|
|
// Now the palette
|
|
//
|
|
|
|
if (bih.biBitCount == BMP_24_BITSPERPIXEL)
|
|
{
|
|
//
|
|
// Just add on the 1 RGBQUAD for the structure but
|
|
// there is no palette
|
|
//
|
|
|
|
cbi += sizeof(RGBQUAD);
|
|
}
|
|
else if ((bih.biBitCount == BMP_16_BITSPERPIXEL) ||
|
|
(bih.biBitCount == BMP_32_BITSPERPIXEL))
|
|
{
|
|
//
|
|
// Add on the 3 DWORD masks which are used to
|
|
// get the colors out of the data
|
|
//
|
|
|
|
cbi += (3 * sizeof(DWORD));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Anything else we just use the bit count to calculate
|
|
// the number of entries
|
|
//
|
|
|
|
cbi += ((1 << bih.biBitCount) * sizeof(RGBQUAD));
|
|
}
|
|
|
|
//
|
|
// Now allocate the BITMAPINFO
|
|
//
|
|
|
|
pbi = (LPBITMAPINFO) new BYTE [cbi];
|
|
if (pbi == NULL)
|
|
{
|
|
hr = ResultFromScode(E_OUTOFMEMORY);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fill in the BITMAPINFO data structure and get the bits
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// First copy the header data
|
|
//
|
|
|
|
memcpy(&(pbi->bmiHeader), &bih, sizeof(BITMAPINFOHEADER));
|
|
|
|
//
|
|
// Now the palette data
|
|
//
|
|
|
|
if (bih.biBitCount == BMP_24_BITSPERPIXEL)
|
|
{
|
|
//
|
|
// No palette data to copy
|
|
//
|
|
}
|
|
else if ((bih.biBitCount == BMP_16_BITSPERPIXEL) ||
|
|
(bih.biBitCount == BMP_32_BITSPERPIXEL))
|
|
{
|
|
//
|
|
// Copy the 3 DWORD masks
|
|
//
|
|
|
|
memcpy(&(pbi->bmiColors), pbBitmapBits, 3*sizeof(DWORD));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If we were a BITMAPCOREHEADER type then we have our
|
|
// palette data in the form of RGBTRIPLEs so we must
|
|
// explicitly copy each. Otherwise we can just memcpy
|
|
// the RGBQUADs
|
|
//
|
|
|
|
if (dwSizeOfHeader == sizeof(BITMAPCOREHEADER))
|
|
{
|
|
ULONG cPalEntry = (1 << bih.biBitCount);
|
|
ULONG cCount;
|
|
RGBTRIPLE *argbt = (RGBTRIPLE *)pbBitmapBits;
|
|
|
|
for (cCount = 0; cCount < cPalEntry; cCount++)
|
|
{
|
|
pbi->bmiColors[cCount].rgbRed =
|
|
argbt[cCount].rgbtRed;
|
|
pbi->bmiColors[cCount].rgbGreen =
|
|
argbt[cCount].rgbtGreen;
|
|
pbi->bmiColors[cCount].rgbBlue =
|
|
argbt[cCount].rgbtBlue;
|
|
|
|
pbi->bmiColors[cCount].rgbReserved = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ULONG cbPalette = (1 << bih.biBitCount) * sizeof(RGBQUAD);
|
|
|
|
memcpy(&(pbi->bmiColors), pbBitmapBits, cbPalette);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now find out where the bits are
|
|
//
|
|
|
|
pbBitmapBits = pbStart + bmfh.bfOffBits;
|
|
|
|
//
|
|
// Get the size to copy
|
|
//
|
|
|
|
cbData = cbLen - bmfh.bfOffBits;
|
|
|
|
//
|
|
// Allocate the buffer to hold the bits
|
|
//
|
|
|
|
pbData = new BYTE [cbData];
|
|
if (pbData == NULL)
|
|
{
|
|
hr = ResultFromScode(E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
memcpy(pbData, pbBitmapBits, cbData);
|
|
}
|
|
}
|
|
|
|
//
|
|
// If everything succeeded record the data
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// Record the info
|
|
//
|
|
|
|
*pcbBitmapInfo = cbi;
|
|
*ppBitmapInfo = pbi;
|
|
|
|
//
|
|
// Record the data
|
|
//
|
|
|
|
*ppBits = pbData;
|
|
*pcbBits = cbData;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Cleanup
|
|
//
|
|
|
|
delete pbi;
|
|
delete pbData;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
#endif // ARC_MINIMAL_UI
|
|
|
|
|
|
|
|
|