📄 menubutton.c
字号:
if (!(hmnu = CreatePopupMenu (&mii))) return 0; pmbi = mb_data->first_item; while (pmbi) { memset (&mii, 0, sizeof(MENUITEMINFO)); mii.state = 0; mii.id = index + _OFF_CMDID; if (pmbi->text && pmbi->bmp) { mii.type = MFT_BMPSTRING; mii.hbmpChecked = pmbi->bmp; mii.hbmpUnchecked = pmbi->bmp; mii.typedata = (DWORD)pmbi->text; } else if (pmbi->text) { mii.type = MFT_STRING; mii.typedata = (DWORD)pmbi->text; } else if (pmbi->bmp) { mii.type = MFT_BITMAP; mii.hbmpChecked = pmbi->bmp; mii.hbmpUnchecked = pmbi->bmp; } else goto error; if (InsertMenuItem (hmnu, index, TRUE, &mii)) goto error; index ++; pmbi = pmbi->next; } if (index == 0) goto error; GetClientRect (hWnd, &rc); ClientToScreen (hWnd, &rc.left, &rc.top); TrackPopupMenu (GetPopupSubMenu (hmnu), TPM_LEFTALIGN, rc.left, rc.top, hWnd); return hmnu;error: DestroyMenu (hmnu); return 0;}static int MenuButtonCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam){ PMENUBTNDATA mb_data; switch (message) { case MSG_CREATE: if ((mb_data = (MENUBTNDATA *) calloc (1, sizeof(MENUBTNDATA))) == NULL) return -1; SetWindowAdditionalData2 (hWnd, (DWORD) mb_data); if (!mbInitMenuButtonData (mb_data, DEF_MB_BUFFER_LEN)) { free (mb_data); return -1; } break; case MSG_DESTROY: mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); mbMenuButtonCleanUp (mb_data); free (mb_data); break; case MBM_SETSTRCMPFUNC: mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); if (mb_data->item_count == 0 && lParam) { mb_data->str_cmp = (STRCMP)lParam; return MB_OKAY; } return MB_ERR; case MBM_ADDITEM: { PMBITEM newItem; int pos; PMENUBUTTONITEM want = (PMENUBUTTONITEM)lParam; DWORD style = GetWindowStyle (hWnd);#if _USE_FIXSTR int len;#endif mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); newItem = mbAllocItem (mb_data); if (!newItem) { NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_ERRSPACE); return MB_ERR_SPACE; }#if _USE_FIXSTR len = strlen (want->text); newItem->text = FixStrAlloc (len); if (!newItem->text) { mbFreeItem (mb_data, newItem); return MB_ERR_SPACE; } if (len > 0) strcpy (newItem->text, want->text);#else newItem->text = strdup (want->text); if (!newItem->text) { mbFreeItem (mb_data, newItem); return MB_ERR_SPACE; }#endif newItem->bmp = want->bmp; newItem->data = want->data; pos = mbAddNewItem (style, mb_data, newItem, (int)wParam); return pos; } case MBM_DELITEM: { PMBITEM removed; int delete = (int)wParam; mb_data = (PMENUBTNDATA) GetWindowAdditionalData2 (hWnd); removed = mbRemoveItem (mb_data, &delete); if (removed) {#if _USE_FIXSTR FreeFixStr (removed->text);#else free (removed->text);#endif mbFreeItem (mb_data, removed); mb_data->item_count --; if (mb_data->cur_sel == delete) { mb_data->cur_sel = MB_INV_ITEM; InvalidateRect (hWnd, NULL, TRUE); } return MB_OKAY; } return MB_INV_ITEM; } case MBM_RESETCTRL: mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); mbResetMenuButtonContent (mb_data); InvalidateRect (hWnd, NULL, TRUE); return MB_OKAY; case MBM_GETCURITEM: mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); return mb_data->cur_sel; case MBM_SETCURITEM: { int old, new; new = (int)wParam; mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); old = mb_data->cur_sel; if (new >= 0 && new < mb_data->item_count) { mb_data->cur_sel = new; InvalidateRect (hWnd, NULL, TRUE); } return old; } case MBM_SETITEMDATA: { PMBITEM pmbi; PMENUBUTTONITEM want = (PMENUBUTTONITEM)lParam; mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); pmbi = mbGetItem (mb_data, (int)wParam); if (pmbi == NULL) return MB_INV_ITEM; if (want->which & MB_WHICH_TEXT) {#if _USE_FIXSTR int len; FreeFixStr (pmbi->text); len = strlen (want->text); pmbi->text = FixStrAlloc (len); if (!pmbi->text) { pmbi->text = ""; return MB_ERR_SPACE; } if (len > 0) strcpy (pmbi->text, want->text);#else free (pmbi->text); pmbi->text = strdup (want->text); if (!pmbi->text) { pmbi->text = ""; return MB_ERR_SPACE; }#endif } if (want->which & MB_WHICH_BMP) { pmbi->bmp = want->bmp; } if (want->which & MB_WHICH_ATTDATA) { pmbi->data = want->data; } if ((int)wParam == mb_data->cur_sel) InvalidateRect (hWnd, NULL, TRUE); return MB_OKAY; } case MBM_GETITEMDATA: { PMBITEM pmbi; PMENUBUTTONITEM want = (PMENUBUTTONITEM)lParam; mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); pmbi = mbGetItem (mb_data, (int)wParam); if (pmbi == NULL) return MB_INV_ITEM; if (want->which & MB_WHICH_TEXT) { want->text = pmbi->text; } if (want->which & MB_WHICH_BMP) { want->bmp = pmbi->bmp; } if (want->which & MB_WHICH_ATTDATA) { want->data = pmbi->data; } return MB_OKAY; } case MSG_CHAR: if (wParam == ' ') { mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); mb_data->hmnu = mbPopupMenu (hWnd); if (mb_data->hmnu) NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_STARTMENU); } break; case MSG_LBUTTONDOWN: SetCapture (hWnd); break; case MSG_LBUTTONUP: { int x, y; RECT rcClient; if (GetCapture() != hWnd) break; ReleaseCapture (); x = LOSWORD(lParam); y = HISWORD(lParam); ScreenToClient (hWnd, &x, &y); GetClientRect (hWnd, &rcClient); if (PtInRect (&rcClient, x, y)) { mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); mb_data->hmnu = mbPopupMenu (hWnd); if (mb_data->hmnu) NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_STARTMENU); } break; } case MSG_ENDTRACKMENU: { mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); if (mb_data->hmnu) { DestroyMenu (mb_data->hmnu); NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_ENDMENU); mb_data->hmnu = 0; } break; } case MSG_COMMAND: { int index = wParam - _OFF_CMDID; mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); if (index < mb_data->item_count && index >= 0) { NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_SELECTED); if (index != mb_data->cur_sel) { mb_data->cur_sel = index; NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_CHANGED); InvalidateRect (hWnd, NULL, TRUE); } } break; } case MSG_PAINT: { HDC hdc; RECT rcClient, rcText, rcMenuBar; UINT uFormat; DWORD dwStyle = GetWindowStyle (hWnd); int bk_color = GetWindowBkColor (hWnd); const char* text; BITMAP* bmp; mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd); mbGetRects (hWnd, dwStyle, &rcClient, &rcText, &rcMenuBar); hdc = BeginPaint (hWnd); Draw3DControlFrame (hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom, GetWindowBkColor (hWnd), TRUE); if (mb_data->cur_sel < 0) { text = GetWindowCaption (hWnd); bmp = NULL; } else { PMBITEM pmbi = mbGetItem (mb_data, mb_data->cur_sel); text = pmbi->text; bmp = pmbi->bmp; } if (bmp) { FillBoxWithBitmap (hdc, rcText.left, (rcText.top + rcText.bottom - bmp->bmHeight) >> 1, 0, 0, bmp); rcText.left += bmp->bmWidth + _INTER_BARTEXT; } rcText.left += (_INTER_BARTEXT >> 1); if (text) { uFormat = DT_SINGLELINE | DT_LEFT | DT_VCENTER; SetBkColor (hdc, bk_color); if (dwStyle & WS_DISABLED) { RECT rc = rcText; SetBkMode (hdc, BM_TRANSPARENT); SetTextColor (hdc, PIXEL_lightwhite); OffsetRect (&rc, 1, 1); DrawText (hdc, text, -1, &rc, uFormat); SetTextColor (hdc, PIXEL_darkgray); DrawText (hdc, text, -1, &rcText, uFormat); } else { SetTextColor (hdc, PIXEL_black); DrawText (hdc, text, -1, &rcText, uFormat); } }#ifdef _FLAT_WINDOW_STYLE DrawFlatControlFrameEx (hdc, rcMenuBar.left, rcMenuBar.top, rcMenuBar.right, rcMenuBar.bottom, bk_color, 0, 0);#else Draw3DUpThinFrame (hdc, rcMenuBar.left, rcMenuBar.top, rcMenuBar.right, rcMenuBar.bottom, bk_color);#endif EndPaint (hWnd, hdc); return 0; } default: break; } return DefaultControlProc (hWnd, message, wParam, lParam);}#endif /* _CTRL_MENUBUTTON */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -