|
|
// Copyright (C) Microsoft Corporation 1996-1997, All Rights reserved.
#include "header.h"
#include "cdlg.h"
#include "strtable.h"
#include "cpaldc.h"
// CLockOut for disabling the outer level windows.
#include "lockout.h"
#ifndef IDBMP_CHECK
#include "resource.h"
#endif
static BOOL WINAPI EnumFontProc(HWND hwnd, LPARAM lval); static BOOL WINAPI EnumBidiSettings(HWND hwnd, LPARAM lval);
CDlg::CDlg(HWND hwndParent, UINT idTemplate) { ZERO_INIT_CLASS(CDlg); m_hwndParent = hwndParent; if(g_bWinNT5) m_lpDialogTemplate = (char *)MAKEINTRESOURCEW(idTemplate); else m_lpDialogTemplate = MAKEINTRESOURCE(idTemplate); m_fCenterWindow = TRUE; m_phhCtrl = NULL; m_fUnicode = g_bWinNT5; }
CDlg::CDlg(CHtmlHelpControl* phhCtrl, UINT idTemplate) { ZERO_INIT_CLASS(CDlg); ASSERT(phhCtrl); m_hwndParent = phhCtrl->m_hwnd; if(g_bWinNT5) m_lpDialogTemplate = (char *)MAKEINTRESOURCEW(idTemplate); else m_lpDialogTemplate = MAKEINTRESOURCE(idTemplate); m_fCenterWindow = TRUE; m_phhCtrl = phhCtrl; m_fUnicode = g_bWinNT5; }
int CDlg::DoModal(void) { if (m_phhCtrl) m_phhCtrl->ModalDialog(TRUE); else m_LockOut.LockOut(m_hwndParent) ;
int result = -1; if (m_fUnicode || g_bWinNT5) { result = (int)::DialogBoxParamW(_Module.GetResourceInstance(), (LPCWSTR)m_lpDialogTemplate, m_hwndParent, (DLGPROC) CDlgProc, (LPARAM) this); // Docs say this returns -1 for failure, but returns 0 on
// Win95 like other unimplemented APIs.
if (0 == result) { if (ERROR_CALL_NOT_IMPLEMENTED == GetLastError()) { m_fUnicode = FALSE; goto _Ansi; } } } else { _Ansi: result = (int)::DialogBoxParamA(_Module.GetResourceInstance(), m_lpDialogTemplate, m_hwndParent, (DLGPROC) CDlgProc, (LPARAM) this); }
if (m_phhCtrl) m_phhCtrl->ModalDialog(FALSE);
return result; }
CDlg::~CDlg() { if (m_fModeLess && IsValidWindow(m_hWnd)) DestroyWindow(m_hWnd); if (m_pCheckBox) delete m_pCheckBox; }
void STDCALL CenterWindow(HWND hwndParent, HWND hwnd) { RECT rcParent, rc;
//BUGBUG: This is broken in the multiple monitor case.
if (!hwndParent) hwndParent = GetDesktopWindow();
GetWindowRect(hwndParent, &rcParent); GetWindowRect(hwnd, &rc);
int cx = RECT_WIDTH(rc); int cy = RECT_HEIGHT(rc); int left = rcParent.left + (RECT_WIDTH(rcParent) - cx) / 2; int top = rcParent.top + (RECT_HEIGHT(rcParent) - cy) / 2;
// Make certain we don't cover the tray
// Also make sure that the dialog box is completely visible.
// If its not visible, then let the default happen.
SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0); if (left < rc.left) left = rc.left; if (top < rc.top) top = rc.top;
// BUG 2426: Make sure that the window is visible.
if (left+cx > rc.right) left = rc.right - cx ; if (top+cy > rc.bottom) top = rc.bottom - cy ;
// Make sure that the dialog still fits.
ASSERT(left >= rc.left && top >= rc.top);
// Make sure that the window is completely visible before doing the move:
MoveWindow(hwnd, left, top, cx, cy, TRUE); }
BOOL CALLBACK CDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { CDlg* pThis = (CDlg*) GetWindowLongPtr(hdlg, GWLP_USERDATA);
switch (msg) { case WM_INITDIALOG: // Save this pointer in the window data area
pThis = (CDlg*) lParam; SetWindowLongPtr(hdlg, GWLP_USERDATA, lParam); pThis->m_hWnd = hdlg; pThis->m_fInitializing = TRUE; // reset when IDOK processed
if (pThis->m_fCenterWindow) CenterWindow(pThis->m_hwndParent, pThis->m_hWnd);
if (pThis->m_pBeginOrEnd) pThis->m_pBeginOrEnd(pThis); else pThis->OnBeginOrEnd();
// set the correct font
//
if(g_bWinNT5) EnumChildWindows(hdlg, (WNDENUMPROC) EnumFontProc, 0);
if (g_fBiDi) { // If BiDi, make adjustments to list and combo boxes
EnumChildWindows(hdlg, (WNDENUMPROC) EnumBidiSettings, 0); }
if (pThis->m_aHelpIds) SetWindowLong(hdlg, GWL_EXSTYLE, GetWindowLong(hdlg, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
// If we're threaded, we may be behind our caller
SetWindowPos(hdlg, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
//BUG 2035: Return TRUE to tell windows to set the keyboard focus.
// m_fFocusChanged is FALSE if the derived class hasn't changed it.
return !pThis->m_fFocusChanged;
case WM_COMMAND: { pThis = (CDlg*) GetWindowLongPtr(hdlg, GWLP_USERDATA); if (!pThis || pThis->m_fShuttingDown) return FALSE; // pThis == NULL if a spin control is being initialized
switch (HIWORD(wParam)) { case BN_CLICKED: pThis->OnButton(LOWORD(wParam)); break;
case LBN_SELCHANGE: // same value as CBN_SELCHANGE
pThis->OnSelChange(LOWORD(wParam)); break;
case LBN_DBLCLK: // same value as CBN_DBLCLK
pThis->OnDoubleClick(LOWORD(wParam)); break;
case EN_CHANGE: pThis->OnEditChange(LOWORD(wParam)); break; }
// If m_pmsglist is set, OnCommand will call OnMsg
if (!pThis->OnCommand(wParam, lParam)) return FALSE;
BOOL fResult;
switch (LOWORD(wParam)) { case IDOK: pThis->m_fInitializing = FALSE; fResult = -1;
if (pThis->m_pBeginOrEnd) fResult = pThis->m_pBeginOrEnd(pThis); else fResult = pThis->OnBeginOrEnd();
if (!fResult) break;
if (pThis->m_fModeLess) { pThis->m_fShuttingDown = TRUE; PostMessage(hdlg, WM_CLOSE, 0, 0); } else pThis->m_LockOut.Unlock(); EndDialog(hdlg, TRUE); break;
case IDCANCEL: if (pThis->m_fModeLess) { pThis->m_fShuttingDown = TRUE; PostMessage(hdlg, WM_CLOSE, 0, 0); } else pThis->m_LockOut.Unlock(); EndDialog(hdlg, FALSE); break;
case IDNO: if (pThis->m_fModeLess) { pThis->m_fShuttingDown = TRUE; PostMessage(hdlg, WM_CLOSE, 0, 0); } else pThis->m_LockOut.Unlock(); EndDialog(hdlg, IDNO); break;
case IDRETRY: if (pThis->m_fModeLess) { pThis->m_fShuttingDown = TRUE; PostMessage(hdlg, WM_CLOSE, 0, 0); } else pThis->m_LockOut.Unlock(); EndDialog(hdlg, IDRETRY); break;
default: break; } } break;
case WM_HELP: pThis->OnHelp((HWND) ((LPHELPINFO) lParam)->hItemHandle); break;
case WM_CONTEXTMENU: pThis->OnContextMenu((HWND) wParam); break;
case WM_DRAWITEM: if (!pThis) return FALSE;
if (pThis->m_pCheckBox && GetDlgItem(hdlg, (int)wParam) == pThis->m_pCheckBox->m_hWnd) { ASSERT(IsValidWindow(pThis->m_pCheckBox->m_hWnd)); pThis->m_pCheckBox->DrawItem((DRAWITEMSTRUCT*) lParam); return TRUE; } else return (int)pThis->OnDlgMsg(msg, wParam, lParam);
case WM_VKEYTOITEM: if (pThis && pThis->m_pCheckBox && (HWND) lParam == pThis->m_pCheckBox->m_hWnd) { if (LOWORD(wParam) == VK_SPACE) { int cursel = (int)pThis->m_pCheckBox->GetCurSel(); if (cursel != LB_ERR) pThis->m_pCheckBox->ToggleItem(cursel); } return -1; // always perform default action
} else return (int)pThis->OnDlgMsg(msg, wParam, lParam);
default: if (pThis) return (int)pThis->OnDlgMsg(msg, wParam, lParam); else return FALSE; }
return FALSE; }
/***************************************************************************
FUNCTION: CDlg::OnMsg
PURPOSE: Parse an array of messages and ids. If the message is intended for an id, call the associated function.
PARAMETERS: wParam
RETURNS: TRUE if no message was processed (i.e., continue processing). FALSE if message processed
COMMENTS:
MODIFICATION DATES: 16-Apr-1997 [ralphw]
***************************************************************************/
BOOL CDlg::OnMsg(WPARAM wParam) { if (!m_pmsglist) return TRUE;
UINT msg = HIWORD(wParam); UINT id = LOWORD(wParam); const CDLG_MESSAGE_LIST* pmsglist = m_pmsglist;
for (;pmsglist->idControl; pmsglist++) { if (msg == pmsglist->idMessage && id == pmsglist->idControl) { (this->*pmsglist->pfunc)(); return FALSE; } } return TRUE; // continue processing
}
HWND CDlg::DoModeless(void) { HWND hwnd = NULL; m_fModeLess = TRUE; if (m_fUnicode) { hwnd = ::CreateDialogParamW(_Module.GetResourceInstance(), (LPCWSTR)m_lpDialogTemplate, m_hwndParent, (DLGPROC) CDlgProc, (LPARAM) this); if (NULL == hwnd) { if (ERROR_CALL_NOT_IMPLEMENTED == GetLastError()) { m_fUnicode = FALSE; goto _Ansi; } } } else { _Ansi: hwnd = ::CreateDialogParamA(_Module.GetResourceInstance(), m_lpDialogTemplate, m_hwndParent, (DLGPROC) CDlgProc, (LPARAM) this); } ASSERT(IsValidWindow(m_hWnd) && hwnd == m_hWnd); ::ShowWindow(m_hWnd, SW_SHOW); return m_hWnd; }
LRESULT CDlg::OnContextMenu(HWND hwnd) { if (m_aHelpIds) WinHelp(hwnd, m_pszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR) (LPVOID) m_aHelpIds); return 0; }
LRESULT CDlg::OnHelp(HWND hwnd) { if (m_aHelpIds) WinHelp(hwnd, m_pszHelpFile, HELP_WM_HELP, (DWORD_PTR) (LPVOID) m_aHelpIds); return 0; }
static BOOL WINAPI EnumFontProc(HWND hwnd, LPARAM lval) { SendMessage(hwnd, WM_SETFONT, (WPARAM) _Resource.GetUIFont(), FALSE); return TRUE; }
static BOOL WINAPI EnumBidiSettings(HWND hwnd, LPARAM lval) { char szClass[MAX_PATH]; VERIFY(GetClassName(hwnd, szClass, sizeof(szClass)));
// In BiDi, flip the scroll bars to the left side
if (IsSamePrefix(szClass, "LISTBOX", -2) || IsSamePrefix(szClass, "COMBOBOX", -2)) { ::SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LEFTSCROLLBAR | ::GetWindowLong(hwnd, GWL_EXSTYLE)); }
return TRUE; }
void CDlgListBox::RemoveListItem() { int cursel; if ((cursel = (int)GetCurSel()) != LB_ERR) {
// Delete current selection, and select the item below it
DeleteString(cursel); if (cursel < GetCount()) SetCurSel(cursel); else if (cursel > 0) SetCurSel(--cursel); else if (GetCount()) SetCurSel(0); } }
void CDlg::MakeCheckedList(int idLB) { if (!m_pCheckBox) m_pCheckBox = new CDlgCheckListBox; m_pCheckBox->Initialize(*this, idLB); }
CDlgCheckListBox::CDlgCheckListBox() { m_xMargin = GetSystemMetrics(SM_CXBORDER); m_yMargin = GetSystemMetrics(SM_CYBORDER); m_cxDlgFrame = GetSystemMetrics(SM_CXDLGFRAME); m_hbmpCheck = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDBMP_CHECK)); ASSERT(m_hbmpCheck);
BITMAP bmp; GetObject(m_hbmpCheck, sizeof(BITMAP), &bmp); m_cxCheck = bmp.bmWidth / 3; m_cyCheck = bmp.bmHeight; m_iLastSel = LB_ERR; }
CDlgCheckListBox::~CDlgCheckListBox() { DeleteObject(m_hbmpCheck); }
BOOL CDlgCheckListBox::IsItemChecked (int nIndex) const { return (BOOL) GetItemData(nIndex); }
void CDlgCheckListBox::CheckItem(int nIndex, BOOL fChecked /*= TRUE*/) { SetItemData(nIndex, fChecked); InvalidateItem(nIndex); }
void CDlgCheckListBox::ToggleItem (int nIndex) { CheckItem(nIndex, IsItemChecked(nIndex) ? FALSE : TRUE); }
int CDlgCheckListBox::ItemHeight(void) { HDC hdc = GetDC(m_hWnd); SIZE size; VERIFY(GetTextExtentPoint(hdc, "M", 1, &size)); ReleaseDC(m_hWnd, hdc); return size.cy; // + GetSystemMetrics (SM_CYBORDER);
}
void CDlgCheckListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { ASSERT (lpDrawItemStruct != NULL);
// Ignore if not redrawing 1
if (lpDrawItemStruct->itemID != LB_ERR && (lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE))) { CStr cszText; int cbText = (int)GetTextLength(lpDrawItemStruct->itemID); cszText.psz = (PSTR) lcMalloc(cbText + 1); GetText(cszText.psz, cbText + 1, lpDrawItemStruct->itemID);
SetTextColor(lpDrawItemStruct->hDC, GetSysColor((lpDrawItemStruct->itemState & ODS_SELECTED) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT)); SetBkColor(lpDrawItemStruct->hDC, GetSysColor((lpDrawItemStruct->itemState & ODS_SELECTED) ? COLOR_HIGHLIGHT : COLOR_WINDOW));
RECT rcItem; RECT rcCheck; GetItemRect(&rcItem, lpDrawItemStruct->itemID); GetCheckRect(lpDrawItemStruct->itemID, &rcCheck);
int yTextOffset = max(0, (RECT_HEIGHT(rcItem) - ItemHeight()) / 2); int xTextOffset = 2 * m_cxDlgFrame + RECT_WIDTH(rcCheck);
ExtTextOut(lpDrawItemStruct->hDC, rcItem.left + xTextOffset, rcItem.top + yTextOffset, ETO_OPAQUE, &rcItem, cszText, cbText, NULL);
DrawCheck(lpDrawItemStruct->hDC, &rcCheck, IsItemChecked(lpDrawItemStruct->itemID)); } }
void CDlgCheckListBox::InvalidateItem(int nIndex, BOOL fRedraw /*= FALSE*/) { RECT rc;
if (GetItemRect(&rc, nIndex) != LB_ERR) InvalidateRect(m_hWnd, &rc, fRedraw); }
void CDlgCheckListBox::DrawCheck(HDC hdc, RECT* prc, BOOL fChecked) { CPalDC dcBmp(m_hbmpCheck);
BitBlt(hdc, prc->left, prc->top, m_cxCheck, m_cyCheck, dcBmp, m_cyCheck * (fChecked ? 1 : 0), 0, SRCCOPY); }
const int CHECK_MARGIN = 2;
int CDlgCheckListBox::GetCheckRect(int nIndex, RECT* prc) { if (GetItemRect(prc, nIndex) == LB_ERR) return LB_ERR;
prc->left += CHECK_MARGIN; prc->right = prc->left + m_cxCheck; if (RECT_HEIGHT(prc) > m_cyCheck) { int diff = (RECT_HEIGHT(prc) - m_cyCheck) / 2; prc->top += diff; }
return 0; }
void CDlgCheckListBox::OnSelChange(void) { int pos = (int)GetCurSel(); if (pos != LB_ERR) { POINT pt; GetCursorPos(&pt); ScreenToClient(*this, &pt); RECT rc; GetCheckRect(pos, &rc); if (PtInRect(&rc, pt)) ToggleItem(pos); else if (pos == m_iLastSel) ToggleItem(pos); } m_iLastSel = pos; }
|