static BOOL OnInitDialog(HWND hDlg, HWND hwndFocus, LPARAM lParam) { HWND hwndIn = (HWND)lParam; HWND hwndList = GetDlgItem(hDlg, 100); SetProp(hDlg,gsPropName,(HANDLE)hwndIn); CenterWindowOnCursor(hDlg); FillListBox(hDlg,hwndIn); ListBox_SetCurSel(hwndList, 0); FORWARD_WM_NEXTDLGCTL(hDlg, hwndList, TRUE, PostMessage); return FALSE; }
// Instructs the property page to translate the keystroke defined // in lpMsg // // There are a bunch of things we need to accomplish here: // - handle tabbing into the dialog // - handle tabbing back out of the dialog // - pass Esc and Enter keys to the property frame // - pass mnemonics that we don't handle to the property frame STDMETHODIMP CPropertyPageEx::TranslateAccelerator(LPMSG lpMsg) { assert(m_hwndDlg); assert(m_pPageSite); if (!lpMsg) return ResultFromScode(E_POINTER); // We shouldn't be asked to translate messages that aren't intented // for us or one of our child windows with the exception of a TAB // where the property frame is giving us an opportunity to take the // focus assert((lpMsg->hwnd == m_hwndDlg) || (IsChild(m_hwndDlg, lpMsg->hwnd)) || (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_TAB)); // We need to do some special pre-processing for keyboard events if (lpMsg->message == WM_KEYDOWN) { UINT nCode; // First see if the control wants to handle it nCode = FORWARD_WM_GETDLGCODE(lpMsg->hwnd, lpMsg, SendMessage); if (nCode & (DLGC_WANTALLKEYS | DLGC_WANTMESSAGE)) return ResultFromScode(S_FALSE); switch (lpMsg->wParam) { case VK_TAB: if (IsChild(m_hwndDlg, GetFocus())) { // We already have focus. See if we should pass focus back to // the frame if (AtEndOfTabList(m_hwndDlg)) { // Give the property frame a chance to take the focus if (m_pPageSite->TranslateAccelerator(lpMsg) == S_OK) return NOERROR; } } else { HWND hwnd; // The property frame wants us to take the focus. If the Shift key is // down give focus to the last control in the tab order if (GetKeyState(VK_SHIFT) < 0) { // Get the last control with a WS_TABSTOP hwnd = GetNextDlgTabItem(m_hwndDlg, GetFirstChild(m_hwndDlg), TRUE); } else { // Get the first control with a WS_TABSTOP hwnd = GetNextDlgTabItem(m_hwndDlg, NULL, FALSE); } FORWARD_WM_NEXTDLGCTL(m_hwndDlg, hwnd, TRUE, SendMessage); return NOERROR; } break; case VK_ESCAPE: case VK_CANCEL: // We don't have a Cancel button, but the property frame does so // let it handle it return m_pPageSite->TranslateAccelerator(lpMsg); case VK_EXECUTE: case VK_RETURN: // If the button with focus is a defpushbutton then drop thru and // let the dialog manager handle it; otherwise pass it to the property // frame so it can handle it nCode = (UINT)SendMessage(GetFocus(), WM_GETDLGCODE, 0, 0L); if (nCode & DLGC_DEFPUSHBUTTON) break; // Not a defpushbutton so let the property frame handle it return m_pPageSite->TranslateAccelerator(lpMsg); default: break; } } // Let the dialog manager handle mnemonics, tab, and cursor keys // // We do need to work around a peculiarity of the dialog manager: // IsDialogMessage() will return TRUE for all WM_SYSCHAR messages whether // or not there is a matching mnemonic, because it also calls DefWindowProc() // to check for menu bar mnemonics BOOL bHandled; HWND hFocus; if (lpMsg->message == WM_SYSCHAR) { // Remember the focus window so we can compare after calling IsDialogMessage() hFocus = GetFocus(); } // Call the dialog manager bHandled = IsDialogMessage(m_hwndDlg, lpMsg); if (lpMsg->message == WM_SYSCHAR) { // See if the focus window changed. If it did then IsDialogMessage() // found a control that matched the mnemonic. Don't do this if it was the // system menu though if (lpMsg->wParam != VK_SPACE && GetFocus() == hFocus) { // Didn't change the focus so there was not a matching mnemonic. Let // the property frame handle it return m_pPageSite->TranslateAccelerator(lpMsg); } } return bHandled ? NOERROR : ResultFromScode(S_FALSE); }
HWND IRA_Dialog::NextDlgCtl(HWND hwnd, HWND hwndSetFocus, BOOL fNext) { return FORWARD_WM_NEXTDLGCTL(hwnd, hwndSetFocus, fNext, PostMessage); }
BOOL CDialogMessageBox::DlgProc(UINT Msg,WPARAM wParam,LPARAM lParam) { switch(Msg) { case WM_INITDIALOG: { //получить размеры текста HDC hdc=GetDC(NULL); SelectFont(hdc,gApplication.mhFontCode); SIZE Size; Size.cx=0; Size.cy=0; { //посчитать размеры построчно UINT Length=_tcslen(mszText); UINT i,j; for(i=0;i<Length;++i) { for(j=i+1;j<Length;++j) if(mszText[j]=='\n') break; SIZE LineSize; GetTextExtentPoint32(hdc,mszText+i,j-i,&LineSize); if(Size.cx<LineSize.cx) Size.cx=LineSize.cx; Size.cy+=LineSize.cy; i=j-1; } } ReleaseDC(NULL,hdc); //получить прямоугольник диалога RECT DialogRect; GetWindowRect(mhWindow,&DialogRect); //получить прямоугольник надписи HWND hStaticText=GetDlgItem(mhWindow,IDC_STATIC_TEXT); RECT StaticTextRect; GetWindowRect(hStaticText,&StaticTextRect); //получить прямоугольник области для кнопок HWND hButtonsArea=GetDlgItem(mhWindow,IDC_BUTTON_AREA); RECT ButtonsRect; GetWindowRect(hButtonsArea,&ButtonsRect); //удалить кнопку-область DestroyWindow(hButtonsArea); //получить сдвиг прямоугольника относительно надписи от верхнего края INT ButtonsOffsetY=ButtonsRect.top-StaticTextRect.bottom; //вычислить новый размер диалога INT DialogWidth=DialogRect.right-DialogRect.left-(StaticTextRect.right-StaticTextRect.left)+Size.cx; INT DialogHeight=DialogRect.bottom-DialogRect.top-(StaticTextRect.bottom-StaticTextRect.top)+Size.cy; //получить прямоугольник родительского окна RECT ParentRect; GetWindowRect(mhWndParent,&ParentRect); //указать размер и положение диалога MoveWindow(mhWindow,ParentRect.left+(ParentRect.right-ParentRect.left-DialogWidth)/2,ParentRect.top+(ParentRect.bottom-ParentRect.top-DialogHeight)/2,DialogWidth,DialogHeight,FALSE); //указать размер надписи SetWindowPos(hStaticText,NULL,0,0,Size.cx,Size.cy,SWP_NOMOVE | SWP_NOZORDER); //указать шрифт для надписи FORWARD_WM_SETFONT(hStaticText,gApplication.mhFontCode,FALSE,SendMessage); //указать надпись SetWindowText(hStaticText,mszText); //указать заголовок окна if(mszCaption) SetWindowText(mhWindow,mszCaption); //получить новое положение надписи в диалоге GetWindowRect(hStaticText,&StaticTextRect); MapWindowPoints(NULL,mhWindow,(LPPOINT)&StaticTextRect,2); //вычислить верхнюю координату для кнопок INT ButtonsTop=StaticTextRect.bottom+ButtonsOffsetY; //ширина кнопки - задана в конструкторе INT ButtonWidth=ButtonsRect.right-ButtonsRect.left; //вычислить расстояние между кнопками INT ButtonSpace=ButtonWidth+ButtonWidth/7; //вычислить отступ слева INT ButtonsLeft=StaticTextRect.left+(StaticTextRect.right-StaticTextRect.left-ButtonSpace*mButtonsCount+ButtonSpace-ButtonWidth)/2; //получить высоту кнопки INT ButtonHeight=ButtonsRect.bottom-ButtonsRect.top; //создать кнопки for(UINT i=0;i<mButtonsCount;++i) { HWND hButton=CreateWindowEx(WS_EX_NOPARENTNOTIFY,TEXT("Button"),mszButtonNames[i],WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP | BS_TEXT /*| (i==mDefaultButton ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON)*/ | BS_PUSHBUTTON | (!i ? WS_GROUP : 0), ButtonsLeft+i*ButtonSpace,ButtonsTop,ButtonWidth,ButtonHeight,mhWindow,NULL,GetModuleHandle(NULL),NULL); SetWindowLong(hButton,GWL_USERDATA,i); //указать шрифт FORWARD_WM_SETFONT(hButton,gApplication.mhFontCode,FALSE,SendMessage); } //выполнить TAB FORWARD_WM_NEXTDLGCTL(mhWindow,0,TRUE,PostMessage); //указать иконку if(mhIcon) SendDlgItemMessage(mhWindow,IDC_STATIC_ICON,STM_SETIMAGE,(WPARAM)IMAGE_BITMAP,(LPARAM)mhIcon); } return TRUE; case WM_COMMAND: if(lParam) //получить номер нажатой кнопки и закрыть диалог EndDialog(mhWindow,GetWindowLong((HWND)lParam,GWL_USERDATA)); return TRUE; } return FALSE; }
/** * @param hwnd - window handle. * @param uMsg - message identifier. * @param wParam - first message parameter. * @param lParam - second message parameter. */ LRESULT CALLBACK CHyperLink::HyperLinkWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int x, y, nCtrlID; POINT point; HCURSOR hCursor; COLORREF rgbNewColor; PAINTSTRUCT ps; HWND hwndParent, hwndCtrl; LRESULT lResult; DWORD dwResult; HDC hdc; CHyperLink* _this = (CHyperLink*)GetWindowLongPtr(hwnd, GWLP_USERDATA); switch(uMsg) { case WM_NCHITTEST: return HTCLIENT; case WM_SETCURSOR: hCursor = g_pResManager->m_hArrowCursor; if (g_pResManager->m_hHandCursor) { dwResult = GetMessagePos(); point.x = GET_X_LPARAM(dwResult); point.y = GET_Y_LPARAM(dwResult); ScreenToClient(hwnd, &point); if (_this->HitTest(point)) hCursor = g_pResManager->m_hHandCursor; } if (hCursor) { SetCursor(hCursor); return TRUE; } return FALSE; case WM_LBUTTONDOWN: if (GetCapture() != hwnd) { x = GET_X_LPARAM(lParam); y = GET_Y_LPARAM(lParam); if (_this->HitTest(x, y)) { _this->m_rgbCurrentColor = m_rgbRedColor; SetCapture(hwnd); if (GetFocus() == hwnd) InvalidateRect(hwnd, NULL, FALSE); else SetFocus(hwnd); } } return 0; case WM_MOUSEMOVE: if (GetCapture() == hwnd) { x = GET_X_LPARAM(lParam); y = GET_Y_LPARAM(lParam); rgbNewColor = _this->HitTest(x, y) ? m_rgbRedColor : m_rgbBlueColor; if (_this->m_rgbCurrentColor != rgbNewColor) { _this->m_rgbCurrentColor = rgbNewColor; InvalidateRect(hwnd, NULL, FALSE); } } return 0; case WM_LBUTTONUP: if (GetCapture() == hwnd) { ReleaseCapture(); x = GET_X_LPARAM(lParam); y = GET_Y_LPARAM(lParam); if (_this->HitTest(x, y)) _this->DoAction(); } return 0; case WM_SETFOCUS: hwndParent = GetParent(hwnd); if (hwndParent) { nCtrlID = GetDlgCtrlID(hwnd); if (_this->m_nPrevDefButtonID < 0) { lResult = SendMessage(hwndParent, DM_GETDEFID, 0, 0); _this->m_nPrevDefButtonID = HIWORD(lResult) == DC_HASDEFID && LOWORD(lResult) != nCtrlID ? LOWORD(lResult) : -1; } SendMessage(hwndParent, DM_SETDEFID, nCtrlID, 0); if (_this->m_nPrevDefButtonID > 0) { // Sending a DM_SETDEFID message to change the default button will not always // remove the default state border from the first push button. In these cases, // the application should send a BM_SETSTYLE message to change the first push // button border style. hwndCtrl = GetDlgItem(hwndParent, _this->m_nPrevDefButtonID); if (SendMessage(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) SendMessage(hwndCtrl, BM_SETSTYLE, BS_PUSHBUTTON, TRUE); } } InvalidateRect(hwnd, NULL, FALSE); return 0; case WM_KILLFOCUS: hwndParent = GetParent(hwnd); if (hwndParent && wParam && IsChild(hwndParent, (HWND)wParam)) { if (! (SendMessage((HWND)wParam, WM_GETDLGCODE, 0, 0) & (DLGC_DEFPUSHBUTTON | DLGC_UNDEFPUSHBUTTON))) { if (_this->m_nPrevDefButtonID > 0) { nCtrlID = _this->m_nPrevDefButtonID; _this->m_nPrevDefButtonID = -1; } else nCtrlID = IDOK; hwndCtrl = GetDlgItem(hwndParent, nCtrlID); if (hwndCtrl && IsWindowEnabled(hwndCtrl)) SendMessage(hwndParent, DM_SETDEFID, nCtrlID, 0); } else { _this->m_nPrevDefButtonID = -1; nCtrlID = GetDlgCtrlID((HWND)wParam); SendMessage(hwndParent, DM_SETDEFID, nCtrlID, 0); } } InvalidateRect(hwnd, NULL, FALSE); return 0; case WM_CAPTURECHANGED: _this->m_rgbCurrentColor = m_rgbBlueColor; InvalidateRect(hwnd, NULL, FALSE); return 0; case WM_ERASEBKGND: return TRUE; case WM_PAINT: hdc = (HDC)wParam; if (! hdc) { hdc = BeginPaint(hwnd, &ps); if (hdc) { _this->DrawHyperLink(hdc); EndPaint(hwnd, &ps); } } else _this->DrawHyperLink(hdc); return 0; case WM_PRINTCLIENT: hdc = (HDC)wParam; _this->DrawHyperLink(hdc); return 0; case WM_KEYDOWN: switch (wParam) { case VK_RETURN: _this->DoAction(); break; case VK_TAB: hwndParent = GetParent(hwnd); if (hwndParent) { BOOL bPrevCtrl = GetKeyState(VK_SHIFT) < 0; FORWARD_WM_NEXTDLGCTL(hwndParent, bPrevCtrl, FALSE, PostMessage); // ToDo: Fix This Define } break; case VK_LEFT: case VK_UP: hwndParent = GetParent(hwnd); if (hwndParent) FORWARD_WM_NEXTDLGCTL(hwndParent, TRUE, FALSE, PostMessage); break; case VK_RIGHT: case VK_DOWN: hwndParent = GetParent(hwnd); if (hwndParent) FORWARD_WM_NEXTDLGCTL(hwndParent, FALSE, FALSE, PostMessage); break; case VK_ESCAPE: hwndParent = GetParent(hwnd); if (hwndParent) { HWND hwndCtl = GetDlgItem(hwndParent, IDCANCEL); if (! hwndCtl || IsWindowEnabled(hwndCtl)) FORWARD_WM_COMMAND(hwndParent, IDCANCEL, hwndCtl, BN_CLICKED, PostMessage); } break; } return 0; case WM_GETDLGCODE: return ((GetFocus() == hwnd ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON) | DLGC_WANTALLKEYS); case BM_SETSTYLE: return 0; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } }