CTRLPROC.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:13k
源码类别:
Windows编程
开发平台:
Visual C++
- /******************************************************************************
- * This is a part of the Microsoft Source Code Samples.
- * Copyright (C) 1993-1997 Microsoft Corporation.
- * All rights reserved.
- * This source code is only intended as a supplement to
- * Microsoft Development Tools and/or WinHelp documentation.
- * See these sources for detailed information regarding the
- * Microsoft samples programs.
- ******************************************************************************/
- /****************************** Module Header *******************************
- * Module Name: ctrlproc.c
- *
- * Contains the window procedures for controls in the dialog being edited.
- *
- * Functions:
- *
- * DialogCtrlWndProc()
- * CtrlWndProc()
- * ChildWndProc()
- * DrawOwnerDrawButton()
- *
- * Comments:
- *
- ****************************************************************************/
- #include "dlgedit.h"
- #include "dlgfuncs.h"
- #include "dlgextrn.h"
- /************************************************************************
- * DialogCtrlWndProc
- *
- * This is the window procedure that subclasses the dialog being
- * edited. It handles a few messages that have to be special-cased
- * for the dialog. Most messages, however, are passed on to the
- * generic control subclass procedure (CtrlWndProc).
- *
- * Arguments:
- * HWND - Handle to the dialog window
- * UINT - window message
- * WPARAM - message parameter
- * LPARAM - message parameter
- *
- * Returns:
- * The default window procedure
- *
- ************************************************************************/
- WINDOWPROC DialogCtrlWndProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- POINT pt;
- BOOL fTracking;
- switch (msg) {
- case WM_NCPAINT:
- case WM_PAINT:
- if (gfTrackRectShown) {
- fTracking = TRUE;
- HideTrackRect();
- }
- else {
- fTracking = FALSE;
- }
- /*
- * Allow the dialog to paint first.
- */
- CallWindowProc((WNDPROC)CtrlWndProc, hwnd, msg, wParam, lParam);
- /*
- * Draw the handles if the dialog is selected.
- */
- if (gfDlgSelected) {
- HDC hDC;
- hDC = GetWindowDC(hwnd);
- DrawHandles(hwnd, hDC, TRUE);
- ReleaseDC(hwnd, hDC);
- }
- if (fTracking)
- ShowTrackRect();
- break;
- case WM_LBUTTONDOWN:
- /*
- * Discard all mouse messages during certain operations.
- */
- if (gfDisabled)
- break;
- /*
- * Also, be sure any outstanding changes get applied
- * without errors.
- */
- if (!StatusApplyChanges())
- break;
- /*
- * Check to see if we are in a normal mode. If we are
- * in some other mode, like dragging a new control,
- * we want to ignore this mouse down and wait for the
- * mouse up. For instance, this can happen when the
- * Duplicate command is selected from the Edit menu.
- */
- if (gState == STATE_NORMAL) {
- ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
- MapDlgClientPoint(&pt, TRUE);
- /*
- * Is the dialog selected and was one of its handles hit?
- * If so, call CtrlButtonDown as if we are a drag window.
- */
- if (gfDlgSelected &&
- HandleHitTest(hwnd, pt.x, pt.y) != DRAG_CENTER) {
- CtrlButtonDown(hwnd, pt.x, pt.y, TRUE);
- }
- else {
- /*
- * If the click was within the client area and
- * there is not a tool selected, start an outline
- * selection operation. Otherwise call CtrlButtonDown
- * which will either begin dragging the dialog or
- * dragging the new control.
- */
- if (gCurTool == W_NOTHING &&
- PtInRect(&grcDlgClient, pt))
- OutlineSelectBegin(pt.x, pt.y);
- else
- CtrlButtonDown(hwnd, pt.x, pt.y, FALSE);
- }
- }
- break;
- case WM_MOUSEMOVE:
- ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
- /*
- * If we are not dragging a new control, then this
- * message is for the dialog, and we map it from
- * the dialog client to the dialog window.
- */
- if (gState != STATE_DRAGGINGNEW)
- MapDlgClientPoint(&pt, TRUE);
- /*
- * Now we process the mouse move message. If the dialog is
- * selected, and if we are not dragging a new control, we
- * pass in a TRUE for fDragWindow. This is because the
- * dialog itself does not have a separate drag window like
- * controls, and if it is selected this message needs to
- * be processed as if a drag window was hit.
- */
- CtrlMouseMove(hwnd,
- (gfDlgSelected && gState != STATE_DRAGGINGNEW) ?
- TRUE : FALSE, pt.x, pt.y);
- break;
- case WM_LBUTTONUP:
- ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
- /*
- * If we are not dragging a new control, then this
- * message is for the dialog, and we map it from
- * the dialog client to the dialog window.
- */
- if (gState != STATE_DRAGGINGNEW)
- MapDlgClientPoint(&pt, TRUE);
- CtrlButtonUp(pt.x, pt.y);
- break;
- case WM_DRAWITEM:
- return DrawOwnerDrawButton((LPDRAWITEMSTRUCT)lParam);
- default:
- return CallWindowProc(
- (WNDPROC)CtrlWndProc, hwnd, msg, wParam, lParam);
- }
- return 0L;
- }
- /************************************************************************
- * CtrlWndProc
- *
- * This is the window procedure that subclasses all of the controls.
- * The dialog being edited will also pass messages that it does not
- * handle through this procedure.
- *
- * Arguments:
- * HWND - Handle to the control window
- * UINT - window message
- * WPARAM - message parameter
- * LPARAM - message parameter
- *
- * Returns:
- * The default window procedure
- *
- ************************************************************************/
- WINDOWPROC CtrlWndProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- POINT pt;
- switch (msg) {
- case WM_NCPAINT:
- case WM_PAINT:
- {
- BOOL fTracking;
- if (gfTrackRectShown) {
- fTracking = TRUE;
- HideTrackRect();
- }
- else {
- fTracking = FALSE;
- }
- /*
- * Allow the control to paint first.
- */
- CallWindowProc((WNDPROC)PCFROMHWND(hwnd)->pwcd->pfnOldWndProc,
- hwnd, msg, wParam, lParam);
- if (fTracking)
- ShowTrackRect();
- }
- break;
- case WM_SETCURSOR:
- /*
- * Defeat the system changing cursors on us. We do it based
- * on our own hit testing.
- */
- return TRUE;
- case WM_TIMER:
- PreDragTimeout(hwnd, TRUE);
- break;
- case WM_LBUTTONDOWN:
- ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
- CtrlButtonDown(hwnd, pt.x, pt.y, FALSE);
- break;
- case WM_MOUSEMOVE:
- ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
- CtrlMouseMove(hwnd, FALSE, pt.x, pt.y);
- break;
- case WM_LBUTTONUP:
- ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
- CtrlButtonUp(pt.x, pt.y);
- break;
- case WM_LBUTTONDBLCLK:
- if (gfDisabled)
- break;
- /*
- * Also, be sure any outstanding changes get applied
- * without errors.
- */
- if (!StatusApplyChanges())
- break;
- StylesDialog();
- break;
- case WM_NCHITTEST:
- return HTCLIENT;
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDBLCLK:
- case WM_MBUTTONDBLCLK:
- /*
- * Helps prevent anything from happening when
- * the middle or right mouse buttons are pressed
- * (or doubleclicked).
- */
- break;
- case WM_MOUSEACTIVATE:
- /*
- * Defeat this message so that mouse clicks do not activate
- * the control.
- */
- return MA_NOACTIVATE;
- case WM_DESTROY:
- /*
- * Unsubclass the control.
- */
- SetWindowLong(hwnd, GWL_WNDPROC,
- (DWORD)(WNDPROC)(PCFROMHWND(hwnd)->pwcd->pfnOldWndProc));
- UNSETPCINTOHWND(hwnd);
- break;
- default:
- return CallWindowProc(
- (WNDPROC)PCFROMHWND(hwnd)->pwcd->pfnOldWndProc,
- hwnd, msg, wParam, lParam);
- }
- return 0L;
- }
- /************************************************************************
- * ChildWndProc
- *
- * This is the window procedure that subclasses all of the children
- * of controls that have them. Currently this is only comboboxes.
- *
- * Arguments:
- * HWND - Handle to the child control window
- * UINT - window message
- * WPARAM - message parameter
- * LPARAM - message parameter
- *
- * Returns:
- * The default window procedure
- *
- ************************************************************************/
- WINDOWPROC ChildWndProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- /*
- * Is this a mouse message?
- */
- if (msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST) {
- POINT pt;
- /*
- * Yes, convert the coordinates and send it to the parent.
- */
- ((pt).x = (SHORT)LOWORD(lParam), (pt).y = (SHORT)HIWORD(lParam));
- ClientToScreen(hwnd, &pt);
- ScreenToClient(GetParent(hwnd), &pt);
- POINT2LONG(pt, lParam);
- SendMessage(GetParent(hwnd), msg, wParam, lParam);
- return FALSE;
- }
- else if (msg == WM_SETCURSOR) {
- /*
- * Defeat the system changing cursors on us. We do it based
- * on our own hit testing.
- */
- return TRUE;
- }
- else if (msg == WM_NCDESTROY) {
- /*
- * Unsubclass the child.
- */
- SetWindowLong(hwnd, GWL_WNDPROC, (DWORD)(WNDPROC)GETCHILDPROC(hwnd));
- /*
- * When destroying the child window, we must be sure and
- * remove the properties associated with it.
- */
- UNSETCHILDPROC(hwnd);
- return 0;
- }
- else {
- /*
- * A benign message, call the class proc.
- */
- return CallWindowProc(GETCHILDPROC(hwnd), hwnd, msg, wParam, lParam);
- }
- }
- /************************************************************************
- * DrawOwnerDrawButton
- *
- * Draws the owner-draw buttons.
- *
- * Arguments:
- * LPDRAWITEMSTRUCT - owner-draw item structure
- *
- * Returns:
- * TRUE if the button was drawn; FALSE if the button could not be drawn.
- *
- ************************************************************************/
- BOOL DrawOwnerDrawButton(
- LPDRAWITEMSTRUCT lpdis)
- {
- TCHAR szText[CCHTEXTMAX];
- if (lpdis->CtlType != ODT_BUTTON || lpdis->itemAction != ODA_DRAWENTIRE)
- return FALSE;
- RoundRect(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
- lpdis->rcItem.right, lpdis->rcItem.bottom, 4, 4);
- GetWindowText(lpdis->hwndItem, szText, CCHTEXTMAX);
- SetBkMode(lpdis->hDC, TRANSPARENT);
- if (gcd.hFont)
- SelectObject(lpdis->hDC, gcd.hFont);
- #ifdef JAPAN
- {
- TCHAR szTmp[CCHTEXTMAX];
- KDExpandCopy(szTmp, szText, CCHTEXTMAX);
- lstrcpy(szText, szTmp);
- }
- #endif
- DrawText(lpdis->hDC, szText, -1, &lpdis->rcItem,
- DT_CENTER | DT_NOCLIP | DT_VCENTER | DT_SINGLELINE);
- return TRUE;
- }