⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 combo.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
{
   if( lphc->wState & CBF_CAPTURE )
   {
       lphc->wState &= ~CBF_CAPTURE;
       if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
       {
	   INT index = CBUpdateLBox( lphc, TRUE );
	   /* Update edit only if item is in the list */
	   if(index >= 0)
	   {
	       lphc->wState |= CBF_NOLBSELECT;
	       CBUpdateEdit( lphc, index );
	       lphc->wState &= ~CBF_NOLBSELECT;
	   }
       }
       ReleaseCapture();
       SetCapture(lphc->hWndLBox);
   }

   if( lphc->wState & CBF_BUTTONDOWN )
   {
       lphc->wState &= ~CBF_BUTTONDOWN;
       CBRepaintButton( lphc );
   }
}

/***********************************************************************
 *           COMBO_MouseMove
 *
 * Two things to do - track combo button and release capture when
 * pointer goes into the listbox.
 */
static void COMBO_MouseMove( LPHEADCOMBO lphc, WPARAM wParam, LPARAM lParam )
{
   POINT  pt;
   RECT   lbRect;

   pt.x = LOWORD(lParam);
   pt.y = HIWORD(lParam);

   if( lphc->wState & CBF_BUTTONDOWN )
   {
     BOOL bButton;

     bButton = PtInRect(&lphc->buttonRect, pt);

     if( !bButton )
     {
       lphc->wState &= ~CBF_BUTTONDOWN;
       CBRepaintButton( lphc );
     }
   }

   GetClientRect( lphc->hWndLBox, &lbRect );
   MapWindowPoints( lphc->self, lphc->hWndLBox, &pt, 1 );
   if( PtInRect(&lbRect, pt) )
   {
       lphc->wState &= ~CBF_CAPTURE;
       ReleaseCapture();
       if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) CBUpdateLBox( lphc, TRUE );

       /* hand over pointer tracking */
       SendMessageW(lphc->hWndLBox, WM_LBUTTONDOWN, wParam, lParam);
   }
}

static LRESULT COMBO_GetComboBoxInfo(LPHEADCOMBO lphc, COMBOBOXINFO *pcbi)
{
    if (!pcbi || (pcbi->cbSize < sizeof(COMBOBOXINFO)))
        return FALSE;

    pcbi->rcItem = lphc->textRect;
    pcbi->rcButton = lphc->buttonRect;
    pcbi->stateButton = 0;
    if (lphc->wState & CBF_BUTTONDOWN)
        pcbi->stateButton |= STATE_SYSTEM_PRESSED;
    if (IsRectEmpty(&lphc->buttonRect))
        pcbi->stateButton |= STATE_SYSTEM_INVISIBLE;
    pcbi->hwndCombo = lphc->self;
    pcbi->hwndItem = lphc->hWndEdit;
    pcbi->hwndList = lphc->hWndLBox;
    return TRUE;
}

static char *strdupA(LPCSTR str)
{
    char *ret;
    DWORD len;

    if(!str) return NULL;

    len = strlen(str);
    ret = HeapAlloc(GetProcessHeap(), 0, len + 1);
    memcpy(ret, str, len + 1);
    return ret;
}

/***********************************************************************
 *           ComboWndProc_common
 *
 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/ctrl/src/combobox_15.htm
 */
static LRESULT ComboWndProc_common( HWND hwnd, UINT message,
                                    WPARAM wParam, LPARAM lParam, BOOL unicode )
{
      LPHEADCOMBO lphc = (LPHEADCOMBO)GetWindowLongPtrW( hwnd, 0 );

      TRACE("[%p]: msg %s wp %08x lp %08lx\n",
            hwnd, SPY_GetMsgName(message, hwnd), wParam, lParam );

      if( lphc || message == WM_NCCREATE )
      switch(message)
      {

	/* System messages */

     	case WM_NCCREATE:
	{
		LONG style = unicode ? ((LPCREATESTRUCTW)lParam)->style :
				       ((LPCREATESTRUCTA)lParam)->style;
                return COMBO_NCCreate(hwnd, style);
	}
     	case WM_NCDESTROY:
		COMBO_NCDestroy(lphc);
		break;/* -> DefWindowProc */

     	case WM_CREATE:
	{
		HWND hwndParent;
		LONG style;
		if(unicode)
		{
		    hwndParent = ((LPCREATESTRUCTW)lParam)->hwndParent;
		    style = ((LPCREATESTRUCTW)lParam)->style;
		}
		else
		{
		    hwndParent = ((LPCREATESTRUCTA)lParam)->hwndParent;
		    style = ((LPCREATESTRUCTA)lParam)->style;
		}
                return COMBO_Create(hwnd, lphc, hwndParent, style, unicode);
	}

        case WM_PRINTCLIENT:
		/* Fallthrough */
     	case WM_PAINT:
		/* wParam may contain a valid HDC! */
		return  COMBO_Paint(lphc, (HDC)wParam);

	case WM_ERASEBKGND:
                /* do all painting in WM_PAINT like Windows does */
                return 1;

	case WM_GETDLGCODE:
	{
		LRESULT result = DLGC_WANTARROWS | DLGC_WANTCHARS;
		if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
		{
		   int vk = (int)((LPMSG)lParam)->wParam;

		   if ((vk == VK_RETURN || vk == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
		       result |= DLGC_WANTMESSAGE;
		}
		return  result;
	}
	case WM_WINDOWPOSCHANGING:
	        return  COMBO_WindowPosChanging(hwnd, lphc, (LPWINDOWPOS)lParam);
    case WM_WINDOWPOSCHANGED:
        /* SetWindowPos can be called on a Combobox to resize its Listbox.
         * In that case, the Combobox itself will not be resized, so we won't
         * get a WM_SIZE. Since we still want to update the Listbox, we have to
         * do it here.
         */
        /* we should not force repainting on WM_WINDOWPOSCHANGED, it breaks
         * Z-order based painting.
         */
        /* fall through */
	case WM_SIZE:
	        if( lphc->hWndLBox &&
                  !(lphc->wState & CBF_NORESIZE) ) COMBO_Size( lphc, message == WM_SIZE );
		return  TRUE;
	case WM_SETFONT:
		COMBO_Font( lphc, (HFONT)wParam, (BOOL)lParam );
		return  TRUE;
	case WM_GETFONT:
		return  (LRESULT)lphc->hFont;
	case WM_SETFOCUS:
		if( lphc->wState & CBF_EDIT )
		    SetFocus( lphc->hWndEdit );
		else
		    COMBO_SetFocus( lphc );
		return  TRUE;
	case WM_KILLFOCUS:
            {
#ifdef __REACTOS__
                HWND hwndFocus = (HWND)wParam;
#else
                HWND hwndFocus = WIN_GetFullHandle( (HWND)wParam );
#endif
		if( !hwndFocus ||
		    (hwndFocus != lphc->hWndEdit && hwndFocus != lphc->hWndLBox ))
		    COMBO_KillFocus( lphc );
		return  TRUE;
            }
	case WM_COMMAND:
#ifdef __REACTOS__
		return  COMBO_Command( lphc, wParam, (HWND)lParam);
#else
		return  COMBO_Command( lphc, wParam, WIN_GetFullHandle( (HWND)lParam ) );
#endif
	case WM_GETTEXT:
            return unicode ? COMBO_GetTextW( lphc, wParam, (LPWSTR)lParam )
                           : COMBO_GetTextA( lphc, wParam, (LPSTR)lParam );
	case WM_SETTEXT:
	case WM_GETTEXTLENGTH:
	case WM_CLEAR:
                if ((message == WM_GETTEXTLENGTH) && !ISWIN31 && !(lphc->wState & CBF_EDIT))
                {
                    int j = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
                    if (j == -1) return 0;
                    return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, j, 0) :
                                     SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, j, 0);
                }
		else if( lphc->wState & CBF_EDIT )
		{
		    LRESULT ret;
		    lphc->wState |= CBF_NOEDITNOTIFY;
		    ret = unicode ? SendMessageW(lphc->hWndEdit, message, wParam, lParam) :
				    SendMessageA(lphc->hWndEdit, message, wParam, lParam);
		    lphc->wState &= ~CBF_NOEDITNOTIFY;
		    return ret;
		}
		else return CB_ERR;
	case WM_CUT:
        case WM_PASTE:
	case WM_COPY:
		if( lphc->wState & CBF_EDIT )
		{
		    return unicode ? SendMessageW(lphc->hWndEdit, message, wParam, lParam) :
				     SendMessageA(lphc->hWndEdit, message, wParam, lParam);
		}
		else return  CB_ERR;

	case WM_DRAWITEM:
	case WM_DELETEITEM:
	case WM_COMPAREITEM:
	case WM_MEASUREITEM:
		return COMBO_ItemOp(lphc, message, lParam);
	case WM_ENABLE:
		if( lphc->wState & CBF_EDIT )
		    EnableWindow( lphc->hWndEdit, (BOOL)wParam );
		EnableWindow( lphc->hWndLBox, (BOOL)wParam );

		/* Force the control to repaint when the enabled state changes. */
		InvalidateRect(lphc->self, NULL, TRUE);
		return  TRUE;
	case WM_SETREDRAW:
		if( wParam )
		    lphc->wState &= ~CBF_NOREDRAW;
		else
		    lphc->wState |= CBF_NOREDRAW;

		if( lphc->wState & CBF_EDIT )
		    SendMessageW(lphc->hWndEdit, message, wParam, lParam);
		SendMessageW(lphc->hWndLBox, message, wParam, lParam);
		return  0;
	case WM_SYSKEYDOWN:
		if( KEYDATA_ALT & HIWORD(lParam) )
		    if( wParam == VK_UP || wParam == VK_DOWN )
			COMBO_FlipListbox( lphc, FALSE, FALSE );
                return  0;

	case WM_CHAR:
	case WM_IME_CHAR:
	case WM_KEYDOWN:
	{
		HWND hwndTarget;

		if ((wParam == VK_RETURN || wParam == VK_ESCAPE) &&
		     (lphc->wState & CBF_DROPPED))
		{
		   CBRollUp( lphc, wParam == VK_RETURN, FALSE );
		   return TRUE;
		}
		else if ((wParam == VK_F4) && !(lphc->wState & CBF_EUI))
		{
		   COMBO_FlipListbox( lphc, FALSE, FALSE );
		   return TRUE;
		}

		if( lphc->wState & CBF_EDIT )
		    hwndTarget = lphc->hWndEdit;
		else
		    hwndTarget = lphc->hWndLBox;

		return unicode ? SendMessageW(hwndTarget, message, wParam, lParam) :
				 SendMessageA(hwndTarget, message, wParam, lParam);
	}
	case WM_LBUTTONDOWN:
		if( !(lphc->wState & CBF_FOCUSED) ) SetFocus( lphc->self );
		if( lphc->wState & CBF_FOCUSED ) COMBO_LButtonDown( lphc, lParam );
		return  TRUE;
	case WM_LBUTTONUP:
		COMBO_LButtonUp( lphc );
		return  TRUE;
	case WM_MOUSEMOVE:
		if( lphc->wState & CBF_CAPTURE )
		    COMBO_MouseMove( lphc, wParam, lParam );
		return  TRUE;

        case WM_MOUSEWHEEL:
                if (wParam & (MK_SHIFT | MK_CONTROL))
                    return unicode ? DefWindowProcW(hwnd, message, wParam, lParam) :
				     DefWindowProcA(hwnd, message, wParam, lParam);

                if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_UP, 0);
                if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_DOWN, 0);
                return TRUE;

	/* Combo messages */

#ifndef __REACTOS__
	case CB_ADDSTRING16:
		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)MapSL(lParam);
		/* fall through */
#endif
	case CB_ADDSTRING:
		if( unicode )
                {
                    if( lphc->dwStyle & CBS_LOWERCASE )
                        CharLowerW((LPWSTR)lParam);
                    else if( lphc->dwStyle & CBS_UPPERCASE )
                        CharUpperW((LPWSTR)lParam);
                    return SendMessageW(lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
                }
                else /* unlike the unicode version, the ansi version does not overwrite
                        the string if converting case */
                {
                    char *string = NULL;
                    LRESULT ret;
                    if( lphc->dwStyle & CBS_LOWERCASE )
                    {
                        string = strdupA((LPSTR)lParam);
                        CharLowerA(string);
                    }
                    else if( lphc->dwStyle & CBS_UPPERCASE )
                    {
                        string = strdupA((LPSTR)lParam);
                        CharUpperA(string);
                    }
                    ret = SendMessageA(lphc->hWndLBox, LB_ADDSTRING, 0, string ? (LPARAM)string : lParam);
                    HeapFree(GetProcessHeap(), 0, string);
                    return ret;
                }
#ifndef __REACTOS__
	case CB_INSERTSTRING16:
		wParam = (INT)(INT16)wParam;
		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)MapSL(lParam);
		/* fall through */
#endif
	case CB_INSERTSTRING:
		if( unicode )
                {
                    if( lphc->dwStyle & CBS_LOWERCASE )
                        CharLowerW((LPWSTR)lParam);
                    else if( lphc->dwStyle & CBS_UPPERCASE )
                        CharUpperW((LPWSTR)lParam);
                    return SendMessageW(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
                }
                else
                {
                    if( lphc->dwStyle & CBS_LOWERCASE )
                        CharLowerA((LPSTR)lParam);
                    else if( lphc->dwStyle & CBS_UPPERCASE )
                        CharUpperA((LPSTR)lParam);
                    return SendMessageA(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
                }
#ifndef __REACTOS__
	case CB_DELETESTRING16:
#endif
	case CB_DELETESTRING:
		return unicode ? SendMessageW(lphc->hWndLBox, LB_DELETESTRING, wParam, 0) :
				 SendMessageA(lphc->hWndLBox, LB_DELETESTRING, wParam, 0);
#ifndef __REACTOS__
	case CB_SELECTSTRING16:
		wParam = (INT)(INT16)wParam;
		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)MapSL(lParam);
		/* fall through */
#endif
	case CB_SELECTSTRING:
		return COMBO_SelectString(lphc, (INT)wParam, lParam, unicode);
#ifndef __REACTOS__
	case CB_FINDSTRING16:
		wParam = (INT)(INT16)wParam;
		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)MapSL(lParam);
		/* fall through */
#endif
	case CB_FINDSTRING:
		return unicode ? SendMessageW(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam) :
				 SendMessageA(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam);
#ifndef __REACTOS__
	case CB_FINDSTRINGEXACT16:
		wParam = (INT)(INT16)wParam;
		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)MapSL(lParam);
		/* fall through */
#endif
	case CB_FINDSTRINGEXACT:
		return unicode ? SendMessageW(lphc->hWndLBox, LB_FINDSTRINGEXACT, wParam, lParam) :
				 SendMessageA(lphc->hWndLBox, LB_FINDSTRINGEXACT, wParam, lParam);
#ifndef __REACTOS__
	case CB_SETITEMHEIGHT16:
		wParam = (INT)(INT16)wParam;	/* signed integer */
		/* fall through */
#endif
	case CB_SETITEMHEIGHT:
		return  COMBO_SetItemHeight( lphc, (INT)wParam, (INT)lParam);
#ifndef __REACTOS__
	case CB_GETITEMHEIGHT16:
		wParam = (INT)(INT16)wParam;
		/* fall through */
#endif
	case CB_GETITEMHEIGHT:
		if( (INT)wParam >= 0 )	/* listbox item */
                    return SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
                return  CBGetTextAreaHeight(hwnd, lphc);
#ifndef __REACTOS__
	case CB_RESETCONTENT16:
#endif
	case CB_RESETCONTENT:
		SendMessageW(lphc->hWndLBox, LB_RESETCONTENT, 0, 0);
                if( (lphc->wState & CBF_EDIT) && CB_HASSTRINGS(lphc) )
		{
		    static const WCHAR empty_st

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -