📄 menubutton.c
字号:
/*
** $Id: menubutton.c,v 1.28 2004/06/26 07:49:31 weiym Exp $
**
** button.c: the Menu Button Control module.
**
** Copyright (C) 2003 Feynman Software.
** Copyright (C) 2000 ~ 2002 Wei Yongming.
**
** Current maintainer: Wei Yongming.
**
** Create date: 2000/11/16
*/
/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
** TODO:
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "minigui.h"
#include "gdi.h"
#include "window.h"
#include "control.h"
#include "cliprect.h"
#include "internals.h"
#include "ctrlclass.h"
#include "ctrlmisc.h"
#ifdef _CTRL_MENUBUTTON
#define _USE_FIXSTR 1
#include "menubutton.h"
#ifdef _FLAT_WINDOW_STYLE
# define _WIDTH_BORDER 1
#define myDrawButton(hdc, hwnd, x0, y0, x1, y1, flags, fillc) \
DrawFlatControlFrameEx(hdc, hwnd, x0, y0, x1, y1, 3, flags, fillc)
#else
# define _WIDTH_BORDER 4
#define myDrawButton Draw3DControlFrameEx
#endif
#ifdef _PHONE_WINDOW_STYLE
const BITMAP* bmp_downarrow;
# define _WIDTH_MENUBAR (bmp_downarrow->bmWidth)
# define _HEIGHT_MENUBAR (bmp_downarrow->bmHeight)
#else
# define _WIDTH_MENUBAR 12
# define _HEIGHT_MENUBAR 8
#endif
#define _INTER_BARTEXT 4
static int MenuButtonCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam);
BOOL RegisterMenuButtonControl (void)
{
WNDCLASS WndClass;
#ifdef _PHONE_WINDOW_STYLE
if ((bmp_downarrow = GetStockBitmap (STOCKBMP_DOWNARROW, 0, 0)) == NULL)
return FALSE;
#endif
WndClass.spClassName = CTRL_MENUBUTTON;
WndClass.dwStyle = WS_NONE;
WndClass.dwExStyle = WS_EX_NONE;
WndClass.hCursor = GetSystemCursor (IDC_ARROW);
WndClass.iBkColor = GetWindowElementColor (BKC_BUTTON_DEF);
WndClass.WinProc = MenuButtonCtrlProc;
return AddNewControlClass (&WndClass) == ERR_OK;
}
#if 0
void MenuButtonControlCleanup (void)
{
return;
}
#endif
static BOOL mbInitMenuButtonData (MENUBTNDATA* mb_data, int len)
{
int i;
PMBITEM pmbi;
mb_data->str_cmp = strncmp;
mb_data->cur_sel = MB_INV_ITEM;
// init item buffer.
if (!(mb_data->buff_head = malloc (len * sizeof (MBITEM))))
return FALSE;
mb_data->buff_len = len;
mb_data->buff_tail = mb_data->buff_head + len;
mb_data->free_list = mb_data->buff_head;
pmbi = mb_data->free_list;
for (i = 0; i < len - 1; i++) {
pmbi->next = pmbi + 1;
pmbi ++;
}
pmbi->next = NULL;
return TRUE;
}
static void mbMenuButtonCleanUp (MENUBTNDATA* mb_data)
{
PMBITEM pmbi;
PMBITEM next;
pmbi = mb_data->first_item;
while (pmbi) {
#if _USE_FIXSTR
FreeFixStr (pmbi->text);
#else
free (pmbi->text);
#endif
next = pmbi->next;
if (pmbi < mb_data->buff_head || pmbi > mb_data->buff_tail)
free (pmbi);
pmbi = next;
}
free (mb_data->buff_head);
}
static void mbResetMenuButtonContent (PMENUBTNDATA mb_data)
{
int i;
PMBITEM pmbi, next;
mb_data->item_count = 0;
mb_data->cur_sel = MB_INV_ITEM;
pmbi = mb_data->first_item;
while (pmbi) {
#if _USE_FIXSTR
FreeFixStr (pmbi->text);
#else
free (pmbi->text);
#endif
next = pmbi->next;
if (pmbi < mb_data->buff_head || pmbi > mb_data->buff_tail)
free (pmbi);
pmbi = next;
}
mb_data->first_item = NULL;
mb_data->free_list = mb_data->buff_head;
pmbi = mb_data->free_list;
for (i = 0; i < mb_data->buff_len - 1; i++) {
pmbi->next = pmbi + 1;
pmbi ++;
}
pmbi->next = NULL;
}
static PMBITEM mbAllocItem (PMENUBTNDATA mb_data)
{
PMBITEM pmbi;
if (mb_data->free_list) {
pmbi = mb_data->free_list;
mb_data->free_list = pmbi->next;
}
else
pmbi = (PMBITEM) malloc (sizeof (MBITEM));
return pmbi;
}
static void mbFreeItem (PMENUBTNDATA mb_data, PMBITEM pmbi)
{
if (pmbi < mb_data->buff_head || pmbi > mb_data->buff_tail)
free (pmbi);
else {
pmbi->next = mb_data->free_list;
mb_data->free_list = pmbi;
}
}
static int mbAddNewItem (DWORD dwStyle,
PMENUBTNDATA mb_data, PMBITEM newItem, int pos)
{
PMBITEM pmbi;
PMBITEM insPosItem = NULL;
int insPos = 0;
newItem->next = NULL;
if (!mb_data->first_item)
insPosItem = NULL;
else if (dwStyle & MBS_SORT) {
pmbi = mb_data->first_item;
if (mb_data->str_cmp (newItem->text, pmbi->text, (size_t)-1) < 0) {
insPosItem = NULL;
insPos = 0;
}
else {
while (pmbi->next) {
if (mb_data->str_cmp (newItem->text, pmbi->next->text, (size_t)-1) <= 0)
break;
pmbi = pmbi->next;
insPos ++;
}
insPosItem = pmbi;
}
}
else {
pmbi = mb_data->first_item;
if (pos < 0) {
while (pmbi->next) {
pmbi = pmbi->next;
insPos ++;
}
insPosItem = pmbi;
}
else if (pos > 0) {
int index = 0;
while (pmbi->next) {
if (pos == index)
break;
pmbi = pmbi->next;
index ++;
insPos ++;
}
insPosItem = pmbi;
}
}
if (insPosItem) {
pmbi = insPosItem->next;
insPosItem->next = newItem;
newItem->next = pmbi;
insPos ++;
}
else {
pmbi = mb_data->first_item;
mb_data->first_item = newItem;
newItem->next = pmbi;
}
mb_data->item_count ++;
return insPos;
}
static PMBITEM mbRemoveItem (PMENUBTNDATA mb_data, int* pos)
{
int index = 0;
PMBITEM pmbi, prev;
if (!mb_data->first_item)
return NULL;
if (*pos < 0) {
prev = mb_data->first_item;
pmbi = mb_data->first_item;
while (pmbi->next) {
prev = pmbi;
pmbi = pmbi->next;
index ++;
}
if (pmbi == mb_data->first_item) {
mb_data->first_item = mb_data->first_item->next;
*pos = 0;
return pmbi;
}
else {
prev->next = pmbi->next;
*pos = index;
return pmbi;
}
}
else if (*pos == 0) {
pmbi = mb_data->first_item;
mb_data->first_item = pmbi->next;
return pmbi;
}
else {
index = 0;
prev = mb_data->first_item;
pmbi = mb_data->first_item;
while (pmbi->next) {
if (*pos == index)
break;
prev = pmbi;
pmbi = pmbi->next;
index ++;
}
if (pmbi == mb_data->first_item) {
mb_data->first_item = mb_data->first_item->next;
*pos = 0;
return pmbi;
}
else {
prev->next = pmbi->next;
*pos = index;
return pmbi;
}
}
return NULL;
}
static PMBITEM mbGetItem (PMENUBTNDATA mb_data, int pos)
{
int index = 0;
PMBITEM pmbi;
pmbi = mb_data->first_item;
while (pmbi) {
if (index == pos)
break;
index ++;
pmbi = pmbi->next;
}
return pmbi;
}
static void mbGetRects (HWND hWnd, DWORD dwStyle,
RECT* prcClient,
RECT* prcText,
RECT* prcMenuBar)
{
GetClientRect (hWnd, prcClient);
prcClient->right --;
prcClient->bottom --;
if (dwStyle & MBS_LEFTARROW) {
SetRect (prcMenuBar, prcClient->left + _WIDTH_BORDER,
(prcClient->top + prcClient->bottom - _HEIGHT_MENUBAR) >> 1,
prcClient->left + _WIDTH_BORDER + _WIDTH_MENUBAR,
(prcClient->top + prcClient->bottom + _HEIGHT_MENUBAR) >> 1);
SetRect (prcText, prcMenuBar->right + _INTER_BARTEXT,
prcClient->top + _WIDTH_BORDER,
prcClient->right - _INTER_BARTEXT,
prcClient->bottom - _WIDTH_BORDER);
}
else {
SetRect (prcText, prcClient->left + _WIDTH_BORDER,
prcClient->top + _WIDTH_BORDER,
prcClient->right - _WIDTH_MENUBAR - (_INTER_BARTEXT << 1),
prcClient->bottom - _WIDTH_BORDER);
SetRect (prcMenuBar, prcText->right + _INTER_BARTEXT,
(prcClient->top + prcClient->bottom - _HEIGHT_MENUBAR) >> 1,
prcClient->right - _INTER_BARTEXT,
(prcClient->top + prcClient->bottom + _HEIGHT_MENUBAR) >> 1);
}
}
#define _OFF_CMDID 100
static HMENU mbPopupMenu (HWND hWnd)
{
HMENU hmnu;
MENUITEMINFO mii;
PMENUBTNDATA mb_data;
int index = 0;
PMBITEM pmbi;
RECT rc;
mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
memset (&mii, 0, sizeof(MENUITEMINFO));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -