📄 menubutton.c
字号:
mii.type = MFT_STRING;
mii.id = 0;
mii.typedata = (DWORD)GetWindowCaption (hWnd);
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, rcText, rcMenuBar;
if (GetCapture() != hWnd)
break;
ReleaseCapture ();
x = LOSWORD(lParam);
y = HISWORD(lParam);
ScreenToClient (hWnd, &x, &y);
mbGetRects (hWnd, GetWindowStyle (hWnd),
&rcClient, &rcText, &rcMenuBar);
if (PtInRect (&rcMenuBar, x, y)) {
mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
mb_data->hmnu = mbPopupMenu (hWnd);
if (mb_data->hmnu)
NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_STARTMENU);
}
else if (PtInRect (&rcClient, x, y)) {
NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_CLICKED);
}
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);
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;
}
hdc = BeginPaint (hWnd);
if (!(dwStyle & MBS_NOBUTTON))
myDrawButton (hdc, hWnd, rcClient.left, rcClient.top,
rcClient.right, rcClient.bottom,
DF_3DBOX_NORMAL | DF_3DBOX_FILL,
GetWindowBkColor (hWnd));
if (bmp) {
if (dwStyle & MBS_LEFTARROW) {
FillBoxWithBitmap (hdc,
rcMenuBar.right + _INTER_BARTEXT,
(rcText.top + rcText.bottom - bmp->bmHeight) >> 1,
0, 0, bmp);
rcText.left += bmp->bmWidth + _INTER_BARTEXT;
}
else {
FillBoxWithBitmap (hdc,
rcMenuBar.left - _INTER_BARTEXT - bmp->bmWidth,
(rcText.top + rcText.bottom - bmp->bmHeight) >> 1,
0, 0, bmp);
rcText.right -= bmp->bmWidth + _INTER_BARTEXT;
}
}
rcText.left += (_INTER_BARTEXT >> 1);
if (text) {
uFormat = DT_SINGLELINE | DT_VCENTER;
switch (dwStyle & MBS_ALIGNMASK) {
case MBS_ALIGNRIGHT:
uFormat |= DT_RIGHT;
break;
case MBS_ALIGNCENTER:
uFormat |= DT_CENTER;
break;
default:
uFormat |= DT_LEFT;
break;
}
SetBkColor (hdc, bk_color);
SetBkMode (hdc, BM_TRANSPARENT);
if (dwStyle & WS_DISABLED) {
RECT rc = rcText;
SetTextColor (hdc, PIXEL_lightwhite);
OffsetRect (&rc, 1, 1);
DrawText (hdc, text, -1, &rc, uFormat);
SetTextColor (hdc, GetWindowElementColorEx (hWnd, FGC_CONTROL_DISABLED));
DrawText (hdc, text, -1, &rcText, uFormat);
}
else {
SetTextColor (hdc, GetWindowElementColorEx (hWnd, FGC_CONTROL_NORMAL));
DrawText (hdc, text, -1, &rcText, uFormat);
}
}
#ifdef _FLAT_WINDOW_STYLE
DrawFlatControlFrameEx (hdc, hWnd, rcMenuBar.left, rcMenuBar.top,
rcMenuBar.right, rcMenuBar.bottom, 0, DF_3DBOX_NORMAL | DF_3DBOX_FILL, bk_color);
#elif defined (_PHONE_WINDOW_STYLE)
FillBoxWithBitmap (hdc, rcMenuBar.left, rcMenuBar.top, 0, 0, bmp_downarrow);
#else
Draw3DThinFrameEx (hdc, hWnd, rcMenuBar.left, rcMenuBar.top,
rcMenuBar.right, rcMenuBar.bottom, DF_3DBOX_NORMAL | DF_3DBOX_FILL, 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 + -