mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-30 06:23:22 +08:00
1228 lines
42 KiB
C
1228 lines
42 KiB
C
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IMPORTANT NOTICE
|
|
//
|
|
// The following open source license statement does not apply to any
|
|
// entity in the Exception List published by FMSoft.
|
|
//
|
|
// For more information, please visit:
|
|
//
|
|
// https://www.fmsoft.cn/exception-list
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
/*
|
|
* This file is part of MiniGUI, a mature cross-platform windowing
|
|
* and Graphics User Interface (GUI) support system for embedded systems
|
|
* and smart IoT devices.
|
|
*
|
|
* Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd.
|
|
* Copyright (C) 1998~2002, WEI Yongming
|
|
*
|
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Or,
|
|
*
|
|
* As this program is a library, any link to this program must follow
|
|
* GNU General Public License version 3 (GPLv3). If you cannot accept
|
|
* GPLv3, you need to be licensed from FMSoft.
|
|
*
|
|
* If you have got a commercial license of this program, please use it
|
|
* under the terms and conditions of the commercial license.
|
|
*
|
|
* For more information about the commercial license, please refer to
|
|
* <http://www.minigui.com/blog/minigui-licensing-policy/>.
|
|
*/
|
|
/*
|
|
** cobmobox.c: the cobmobox control.
|
|
**
|
|
** Created by Jiao Libo at 2001/08/06
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "common.h"
|
|
|
|
#ifdef _MGCTRL_COMBOBOX
|
|
#include "minigui.h"
|
|
#include "gdi.h"
|
|
#include "window.h"
|
|
#include "ctrl/ctrlhelper.h"
|
|
#include "ctrl/edit.h"
|
|
#include "ctrl/listbox.h"
|
|
#include "ctrl/combobox.h"
|
|
#include "cliprect.h"
|
|
#include "internals.h"
|
|
#include "ctrlclass.h"
|
|
|
|
#include "combobox_impl.h"
|
|
#include "ctrlmisc.h"
|
|
|
|
#define LEN_SPINVALUE 50
|
|
|
|
#define IDC_CEDIT 100
|
|
#define IDC_CLISTBOX 101
|
|
|
|
#define INTER_EDIT_BUTTON 2
|
|
#define INTER_EDIT_LISTBOX 4
|
|
#define DEF_LISTHEIGHT 60
|
|
|
|
#define INC_BOX 1
|
|
#define DEC_BOX 2
|
|
static int mouse_old = 0;
|
|
|
|
static LRESULT ComboBoxCtrlProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
|
|
BOOL RegisterComboBoxControl (void)
|
|
{
|
|
WNDCLASS WndClass;
|
|
|
|
WndClass.spClassName = CTRL_COMBOBOX;
|
|
WndClass.dwStyle = WS_NONE;
|
|
WndClass.dwExStyle = WS_EX_NONE;
|
|
WndClass.hCursor = GetSystemCursor (0);
|
|
#ifdef _MGSCHEMA_COMPOSITING
|
|
WndClass.dwBkColor =
|
|
GetWindowElementAttr (HWND_NULL, WE_BGC_WINDOW);
|
|
#else
|
|
WndClass.iBkColor =
|
|
GetWindowElementPixelEx (HWND_NULL, HDC_SCREEN, WE_BGC_WINDOW);
|
|
#endif
|
|
WndClass.WinProc = ComboBoxCtrlProc;
|
|
|
|
return gui_AddNewControlClass (&WndClass) == ERR_OK;
|
|
}
|
|
|
|
static LRESULT AutoSpinEditBoxProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
WNDPROC old_edit_proc;
|
|
|
|
if (message == MSG_CHAR) {
|
|
if (wParam != 127 && (wParam < '0' || wParam > '9'))
|
|
return 0;
|
|
}
|
|
|
|
old_edit_proc = (WNDPROC) GetWindowAdditionalData (hWnd);
|
|
return (*old_edit_proc) (hWnd, message, wParam, lParam);
|
|
}
|
|
|
|
static int DefCBProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam);
|
|
|
|
static void ComboBoxDrawSpinButton (HWND hwnd, HDC hdc , int which, int status)
|
|
{
|
|
PCOMBOBOXDATA pData;
|
|
PCONTROL pCtrl;
|
|
const WINDOWINFO *win_info;
|
|
DWORD fg_3d;
|
|
BOOL bGetDC = FALSE;
|
|
|
|
if (hdc == 0) {
|
|
bGetDC = TRUE;
|
|
hdc = GetClientDC(hwnd);
|
|
}
|
|
|
|
pCtrl = gui_Control (hwnd);
|
|
win_info = GetWindowInfo(hwnd);
|
|
pData = (PCOMBOBOXDATA)pCtrl->dwAddData2;
|
|
|
|
/* not used var
|
|
DWORD main_3d;
|
|
main_3d = GetWindowElementAttr(hwnd, WE_MAINC_THREED_BODY);
|
|
*/
|
|
fg_3d = GetWindowElementAttr(hwnd, WE_FGC_THREED_BODY);
|
|
|
|
if(which == 0)
|
|
status = LFRDR_BTN_STATUS_NORMAL;
|
|
|
|
switch (pCtrl->dwStyle & CBS_TYPEMASK) {
|
|
case CBS_SIMPLE:
|
|
break;
|
|
case CBS_SPINLIST:
|
|
case CBS_AUTOSPIN:
|
|
if (pCtrl->dwStyle & CBS_SPINARROW_LEFTRIGHT)
|
|
{
|
|
if(which == 0 || which == INC_BOX)
|
|
{
|
|
SelectClipRect (hdc, &(pData->IncSpinBox));
|
|
win_info->we_rdr->draw_arrow(hwnd, hdc, &(pData->IncSpinBox),
|
|
fg_3d, status | LFRDR_ARROW_HAVESHELL | LFRDR_ARROW_RIGHT);
|
|
}
|
|
if(which == 0 || which == DEC_BOX)
|
|
{
|
|
SelectClipRect (hdc, &(pData->DecSpinBox));
|
|
win_info->we_rdr->draw_arrow(hwnd, hdc, &(pData->DecSpinBox),
|
|
fg_3d, status | LFRDR_ARROW_HAVESHELL | LFRDR_ARROW_LEFT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(which == 0 || which == INC_BOX)
|
|
{
|
|
SelectClipRect (hdc, &(pData->IncSpinBox));
|
|
win_info->we_rdr->draw_arrow(hwnd, hdc, &(pData->IncSpinBox),
|
|
fg_3d, status | LFRDR_ARROW_HAVESHELL | LFRDR_ARROW_UP);
|
|
}
|
|
if(which == 0 || which == DEC_BOX)
|
|
{
|
|
SelectClipRect (hdc, &(pData->DecSpinBox));
|
|
win_info->we_rdr->draw_arrow(hwnd, hdc, &(pData->DecSpinBox),
|
|
fg_3d, status | LFRDR_ARROW_HAVESHELL | LFRDR_ARROW_DOWN);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
SelectClipRect (hdc, &(pData->IncSpinBox));
|
|
win_info->we_rdr->draw_arrow(hwnd, hdc, &(pData->IncSpinBox), fg_3d,
|
|
status | LFRDR_ARROW_HAVESHELL | LFRDR_ARROW_DOWN);
|
|
break;
|
|
}
|
|
|
|
if(bGetDC)
|
|
{
|
|
ReleaseDC(hdc);
|
|
}
|
|
return ;
|
|
}
|
|
|
|
static void GetSpinBox (PCOMBOBOXDATA pData, DWORD dwStyle,
|
|
const RECT* rect, RECT* edit_box)
|
|
{
|
|
int w, h;
|
|
if (dwStyle & CBS_SPINARROW_TOPBOTTOM)
|
|
{
|
|
w = (rect->right - rect->left) > 16 ? 16 : (rect->right - rect->left);
|
|
h = (rect->bottom - rect->top)>>1;
|
|
h = h > (w>>1)? (w>>1) : h;
|
|
|
|
edit_box->left = rect->left;
|
|
edit_box->top = rect->top + h + INTER_EDIT_BUTTON;
|
|
edit_box->right = rect->right;
|
|
edit_box->bottom = rect->bottom - h - INTER_EDIT_BUTTON;
|
|
|
|
pData->IncSpinBox.left = (rect->right - w)>>1;
|
|
pData->IncSpinBox.right = pData->IncSpinBox.left + w;
|
|
pData->IncSpinBox.top = rect->top;
|
|
pData->IncSpinBox.bottom = rect->top + h;
|
|
|
|
pData->DecSpinBox.left = pData->IncSpinBox.left;
|
|
pData->DecSpinBox.right = pData->IncSpinBox.right;
|
|
pData->DecSpinBox.top = rect->bottom - h;
|
|
pData->DecSpinBox.bottom = rect->bottom;
|
|
}
|
|
else if (dwStyle & CBS_SPINARROW_LEFTRIGHT)
|
|
{
|
|
h = rect->bottom - rect->top;
|
|
w = h < 16 ? h : 16;
|
|
|
|
edit_box->left = rect->left + (w>>1) + INTER_EDIT_BUTTON;
|
|
edit_box->top = rect->top;
|
|
edit_box->bottom = rect->bottom;
|
|
edit_box->right = rect->right - (w>>1) - INTER_EDIT_BUTTON;
|
|
|
|
pData->DecSpinBox.left = rect->left;
|
|
pData->DecSpinBox.top = rect->top + ((h-w)>>1);
|
|
pData->DecSpinBox.right = rect->left + (w>>1);
|
|
pData->DecSpinBox.bottom = pData->DecSpinBox.top + w;
|
|
|
|
pData->IncSpinBox.left = rect->right - (w>>1);
|
|
pData->IncSpinBox.top = pData->DecSpinBox.top;
|
|
pData->IncSpinBox.right = rect->right;
|
|
pData->IncSpinBox.bottom = pData->DecSpinBox.bottom;
|
|
}
|
|
else //updown button on the right
|
|
{
|
|
h = rect->bottom - rect->top;
|
|
w = h < 16 ? h : 16;
|
|
|
|
edit_box->left = rect->left;
|
|
edit_box->top = rect->top;
|
|
edit_box->bottom = rect->bottom;
|
|
edit_box->right = rect->right - w - INTER_EDIT_BUTTON;
|
|
|
|
pData->IncSpinBox.left = rect->right - w;
|
|
pData->IncSpinBox.top = rect->top + (h>>1) - (w>>1);
|
|
pData->IncSpinBox.right = rect->right;
|
|
pData->IncSpinBox.bottom = rect->top + (h>>1) - 1;
|
|
|
|
pData->DecSpinBox.left = rect->right - w;
|
|
pData->DecSpinBox.top = rect->top + (h>>1) + 1;
|
|
pData->DecSpinBox.right = rect->right;
|
|
pData->DecSpinBox.bottom = rect->bottom - (h>>1) + (w >>1);
|
|
}
|
|
}
|
|
|
|
static void OnSizeChanged (PCONTROL pCtrl, DWORD dwStyle, const RECT* rcClient)
|
|
{
|
|
PCOMBOBOXDATA pData;
|
|
int tmpx, tmpy;
|
|
int height, width;
|
|
int w, h;
|
|
RECT edit_box, rect;
|
|
|
|
pData = (PCOMBOBOXDATA)pCtrl->dwAddData2;
|
|
|
|
SetRect (&rect, 0, 0, RECTWP (rcClient), RECTHP (rcClient));
|
|
width = rect.right - rect.left;
|
|
|
|
switch (dwStyle & CBS_TYPEMASK)
|
|
{
|
|
case CBS_SIMPLE:
|
|
height = GetSysFontHeight (SYSLOGFONT_CONTROL) + MARGIN_EDIT_TOP
|
|
+ MARGIN_EDIT_BOTTOM + (WIDTH_EDIT_BORDER<<1);
|
|
edit_box.left = rect.left;
|
|
edit_box.top = rect.top;
|
|
edit_box.right = rect.left + width;
|
|
edit_box.bottom = rect.top + height;
|
|
|
|
pData->ListBoxRect.left = rect.left;
|
|
pData->ListBoxRect.right = rect.right - MARGIN_EDIT_RIGHT;
|
|
pData->ListBoxRect.top = rect.top + height + INTER_EDIT_LISTBOX;
|
|
pData->ListBoxRect.bottom = pData->ListBoxRect.top + pData->list_height;
|
|
break;
|
|
|
|
case CBS_SPINLIST:
|
|
GetSpinBox (pData, dwStyle, &rect, &edit_box);
|
|
pData->spin_pace = 1;
|
|
pData->fastspin_pace = 5;
|
|
break;
|
|
|
|
case CBS_AUTOSPIN:
|
|
GetSpinBox (pData, dwStyle, &rect, &edit_box);
|
|
pData->spin_min = 0;
|
|
pData->spin_max = 100;
|
|
pData->spin_pace = 1;
|
|
pData->fastspin_pace = 5;
|
|
break;
|
|
|
|
default: // now, for CBS_DROPDOWNLIST
|
|
h = RECTH(rect);
|
|
w = h < 16 ? h : 16;
|
|
|
|
edit_box.left = rect.left;
|
|
edit_box.top = rect.top;
|
|
edit_box.bottom = rect.bottom;
|
|
edit_box.right = rect.right - w - INTER_EDIT_BUTTON;
|
|
|
|
pData->DecSpinBox.left = rect.right - w;
|
|
pData->DecSpinBox.top = rect.top + ((h-w)>>1);
|
|
pData->DecSpinBox.right = rect.right;
|
|
pData->DecSpinBox.bottom = pData->DecSpinBox.top + w;
|
|
|
|
pData->IncSpinBox.left = pData->DecSpinBox.left;
|
|
pData->IncSpinBox.top = pData->DecSpinBox.top;
|
|
pData->IncSpinBox.right = pData->DecSpinBox.right;
|
|
pData->IncSpinBox.bottom = pData->DecSpinBox.bottom;
|
|
|
|
pData->ListBoxRect.left = rect.left;
|
|
pData->ListBoxRect.right = rect.right;
|
|
pData->ListBoxRect.top = rect.bottom;
|
|
pData->ListBoxRect.bottom = rect.bottom + pData->list_height;
|
|
break;
|
|
}
|
|
|
|
tmpx = pData->ListBoxRect.right;
|
|
tmpy = pData->ListBoxRect.bottom;
|
|
ClientToScreen ((HWND)pCtrl, &tmpx, &tmpy);
|
|
if (tmpy > g_rcScr.bottom) {
|
|
pData->ListBoxRect.left = rect.left;
|
|
pData->ListBoxRect.right = rect.right;
|
|
pData->ListBoxRect.top = rect.top - pData->list_height;
|
|
pData->ListBoxRect.bottom = rect.top;
|
|
}
|
|
|
|
if (pData->EditControl) {
|
|
ShowWindow(pData->EditControl, SW_SHOW);
|
|
MoveWindow (pData->EditControl, edit_box.left, edit_box.top,
|
|
RECTW(edit_box), RECTH(edit_box), TRUE);
|
|
}
|
|
|
|
if (pData->ListBoxControl) {
|
|
MoveWindow (pData->ListBoxControl,
|
|
pData->ListBoxRect.left, pData->ListBoxRect.top,
|
|
width, pData->list_height, TRUE);
|
|
}
|
|
}
|
|
|
|
static LRESULT ComboBoxCtrlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PCONTROL pCtrl = gui_Control (hwnd);
|
|
PCOMBOBOXDATA pData = (PCOMBOBOXDATA)pCtrl->dwAddData2;
|
|
DWORD dwStyle = pCtrl->dwStyle;
|
|
|
|
switch (message) {
|
|
case MSG_CREATE:
|
|
{
|
|
const char* edit_text = GetWindowCaption (hwnd);
|
|
DWORD list_style, edit_style;
|
|
|
|
if (!(pData = calloc (1, sizeof (COMBOBOXDATA)))) {
|
|
_ERR_PRINTF ("CONTROL>COMBOBOX: failed to allocate memory to create control instance!\n");
|
|
return -1;
|
|
}
|
|
|
|
pData->wStateFlags = 0;
|
|
pData->nListItems = 0;
|
|
pCtrl->dwAddData2 = (DWORD)pData;
|
|
|
|
list_style = WS_VSCROLL | LBS_NOTIFY | WS_THINFRAME;
|
|
if ((dwStyle & CBS_TYPEMASK) == CBS_DROPDOWNLIST)
|
|
list_style |= LBS_MOUSEFOLLOW;
|
|
|
|
if (dwStyle & CBS_SORT) list_style |= LBS_SORT;
|
|
|
|
edit_style = WS_CHILD;
|
|
if (!(dwStyle & CBS_EDITNOBORDER)) edit_style |= WS_BORDER;
|
|
if (dwStyle & CBS_EDITBASELINE) edit_style |= ES_BASELINE;
|
|
if (dwStyle & CBS_UPPERCASE) edit_style |= ES_UPPERCASE;
|
|
if (dwStyle & CBS_LOWERCASE) edit_style |= ES_LOWERCASE;
|
|
if (dwStyle & CBS_READONLY) edit_style |= ES_READONLY;
|
|
|
|
switch (dwStyle & CBS_TYPEMASK) {
|
|
case CBS_SIMPLE:
|
|
list_style |= WS_VISIBLE | WS_BORDER;
|
|
pData->list_height = (pCtrl->dwAddData > 0)
|
|
? pCtrl->dwAddData : DEF_LISTHEIGHT;
|
|
break;
|
|
|
|
case CBS_SPINLIST:
|
|
pData->list_height = 0;
|
|
pData->spin_pace = 1;
|
|
pData->fastspin_pace = 5;
|
|
break;
|
|
|
|
case CBS_AUTOSPIN:
|
|
pData->spin_min = 0;
|
|
pData->spin_max = 100;
|
|
pData->spin_pace = 1;
|
|
pData->fastspin_pace = 5;
|
|
pData->list_height = -1;
|
|
break;
|
|
|
|
default:
|
|
pData->list_height = (pCtrl->dwAddData > 0)
|
|
? pCtrl->dwAddData : DEF_LISTHEIGHT;
|
|
break;
|
|
}
|
|
|
|
if (pCtrl->dwExStyle & WS_EX_TRANSPARENT)
|
|
pData->EditControl = CreateWindowEx (CTRL_SLEDIT,
|
|
edit_text,
|
|
edit_style, WS_EX_TRANSPARENT, IDC_CEDIT,
|
|
0, 0, 10, 10,
|
|
hwnd, 0);
|
|
else
|
|
pData->EditControl = CreateWindow (CTRL_SLEDIT,
|
|
edit_text,
|
|
edit_style, IDC_CEDIT,
|
|
0, 0, 10, 10,
|
|
hwnd, 0);
|
|
|
|
if ((dwStyle & CBS_TYPEMASK) == CBS_AUTOSPIN) {
|
|
WNDPROC old_edit_proc =
|
|
SetWindowCallbackProc (pData->EditControl, AutoSpinEditBoxProc);
|
|
SetWindowAdditionalData (pData->EditControl, (DWORD)old_edit_proc);
|
|
|
|
pData->str_format = strdup ("%d");
|
|
}
|
|
|
|
if (dwStyle & CBS_EDITNOBORDER)
|
|
pCtrl->iBkColor = GetWindowBkColor(pData->EditControl);
|
|
else
|
|
pCtrl->iBkColor = GetWindowBkColor(GetParent(hwnd));
|
|
|
|
if (pData->list_height >= 0) {
|
|
DWORD ex_style = WS_EX_NONE;
|
|
if ((dwStyle & CBS_TYPEMASK) == CBS_SIMPLE) {
|
|
ex_style |= (pCtrl->dwExStyle & WS_EX_TRANSPARENT);
|
|
}
|
|
else{
|
|
ex_style |= WS_EX_CTRLASMAINWIN;
|
|
}
|
|
|
|
pData->ListBoxControl = CreateWindowEx (CTRL_LISTBOX,
|
|
"listbox", list_style, ex_style,
|
|
IDC_CLISTBOX, 0, 0, 0, 0, hwnd, 0);
|
|
}
|
|
else {
|
|
pData->ListBoxControl = 0;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case MSG_DESTROY:
|
|
DestroyAllControls (hwnd);
|
|
free (pData->str_format);
|
|
free (pData);
|
|
return 0;
|
|
|
|
case MSG_SIZECHANGING:
|
|
{
|
|
const RECT* rcExpect = (const RECT*)wParam;
|
|
RECT* rcResult = (RECT*)lParam;
|
|
if ((dwStyle & CBS_TYPEMASK) == CBS_SIMPLE) {
|
|
int height = GetSysFontHeight (SYSLOGFONT_CONTROL)
|
|
+ MARGIN_EDIT_TOP + MARGIN_EDIT_BOTTOM
|
|
+ (WIDTH_EDIT_BORDER<<1);
|
|
|
|
rcResult->left = rcExpect->left;
|
|
rcResult->top = rcExpect->top;
|
|
rcResult->right = rcExpect->right;
|
|
rcResult->bottom = rcExpect->top + height;
|
|
rcResult->bottom += pData->list_height + INTER_EDIT_LISTBOX*2;
|
|
return 0;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case MSG_SIZECHANGED:
|
|
OnSizeChanged (pCtrl, dwStyle, (const RECT*)lParam);
|
|
break;
|
|
|
|
case MSG_CHILDHIDDEN:
|
|
{
|
|
int reason = wParam;
|
|
int x = LOSWORD(lParam);
|
|
int y = HISWORD(lParam);
|
|
|
|
if (reason == RCTM_CLICK)
|
|
ScreenToClient (hwnd, &x, &y);
|
|
|
|
if (IS_SET (pData, CSF_HASDROPPED)) {
|
|
CLEAR_STATE (pData, CSF_HASDROPPED);
|
|
NotifyParent (hwnd, pCtrl->id, CBN_SELECTCANCEL);
|
|
NotifyParent (hwnd, pCtrl->id, CBN_CLOSEUP);
|
|
}
|
|
|
|
if (((dwStyle & CBS_TYPEMASK) > CBS_AUTOSPIN)
|
|
&& PtInRect (&pData->IncSpinBox, x, y))
|
|
SET_STATE (pData, CSF_HASDROPPED);
|
|
break;
|
|
}
|
|
|
|
case MSG_SETFOCUS:
|
|
if (dwStyle & CBS_AUTOFOCUS || dwStyle & WS_TABSTOP)
|
|
SetFocusChild (pData->EditControl);
|
|
if (dwStyle & CBS_NOTIFY)
|
|
NotifyParent (hwnd, pCtrl->id, CBN_SETFOCUS);
|
|
break;
|
|
|
|
case MSG_KILLFOCUS:
|
|
if (((dwStyle & CBS_TYPEMASK) == CBS_DROPDOWNLIST) &&
|
|
IS_SET (pData, CSF_HASDROPPED)) {
|
|
ShowWindow (pData->ListBoxControl, SW_HIDE);
|
|
CLEAR_STATE (pData, CSF_HASDROPPED);
|
|
if (dwStyle & CBS_NOTIFY)
|
|
{
|
|
NotifyParent (hwnd, pCtrl->id, CBN_SELECTCANCEL);
|
|
NotifyParent (hwnd, pCtrl->id, CBN_CLOSEUP);
|
|
}
|
|
}
|
|
if (dwStyle & CBS_NOTIFY)
|
|
NotifyParent (hwnd, pCtrl->id, CBN_KILLFOCUS);
|
|
break;
|
|
|
|
case MSG_LBUTTONDOWN:
|
|
{
|
|
int x = LOSWORD(lParam);
|
|
int y = HISWORD(lParam);
|
|
BOOL inc = FALSE;
|
|
|
|
if (PtInRect (&pData->IncSpinBox, x, y))
|
|
{
|
|
inc = TRUE;
|
|
//SendMessage(hwnd, MSG_PAINT,
|
|
// MAKELONG(INC_BOX, LFRDR_BTN_STATUS_PRESSED), 0);
|
|
ComboBoxDrawSpinButton(hwnd, 0, INC_BOX, LFRDR_BTN_STATUS_PRESSED);
|
|
}
|
|
else if (PtInRect (&pData->DecSpinBox, x, y))
|
|
{
|
|
inc = FALSE;
|
|
//SendMessage(hwnd, MSG_PAINT,
|
|
// MAKELONG(DEC_BOX, LFRDR_BTN_STATUS_PRESSED), 0);
|
|
ComboBoxDrawSpinButton(hwnd, 0, DEC_BOX, LFRDR_BTN_STATUS_PRESSED);
|
|
}
|
|
else
|
|
break;
|
|
|
|
switch (dwStyle & CBS_TYPEMASK) {
|
|
case CBS_SPINLIST:
|
|
SetCapture (hwnd);
|
|
SendMessage (hwnd, CB_SPIN, inc, 0);
|
|
SetAutoRepeatMessage (hwnd, CB_FASTSPIN, inc, 0);
|
|
break;
|
|
case CBS_AUTOSPIN:
|
|
SetCapture (hwnd);
|
|
SendMessage (hwnd, CB_SPIN, !inc, 0);
|
|
SetAutoRepeatMessage (hwnd, CB_FASTSPIN, !inc, 0);
|
|
break;
|
|
|
|
case CBS_DROPDOWNLIST:
|
|
if (IS_SET (pData, CSF_HASDROPPED)) {
|
|
CLEAR_STATE (pData, CSF_HASDROPPED);
|
|
}
|
|
else {
|
|
ShowWindow (pData->ListBoxControl, SW_SHOW);
|
|
SetFocusChild (pData->ListBoxControl);
|
|
SendNotifyMessage (pData->ListBoxControl, MSG_SETFOCUS, 0,0);
|
|
SET_STATE (pData, CSF_HASDROPPED);
|
|
if (dwStyle & CBS_NOTIFY)
|
|
NotifyParent (hwnd, pCtrl->id, CBN_DROPDOWN);
|
|
}
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case MSG_LBUTTONUP:
|
|
{
|
|
int x = LOSWORD(lParam);
|
|
int y = HISWORD(lParam);
|
|
|
|
if(!((dwStyle & CBS_TYPEMASK) == CBS_DROPDOWNLIST))
|
|
ScreenToClient(hwnd, &x, &y);
|
|
|
|
if (PtInRect (&pData->IncSpinBox, x, y))
|
|
{
|
|
//SendMessage(hwnd, MSG_PAINT,
|
|
// MAKELONG(INC_BOX, LFRDR_BTN_STATUS_HILITE), 0);
|
|
ComboBoxDrawSpinButton(hwnd, 0, INC_BOX, LFRDR_BTN_STATUS_HILITE);
|
|
mouse_old = INC_BOX;
|
|
}
|
|
else if (PtInRect (&pData->DecSpinBox, x, y))
|
|
{
|
|
//SendMessage(hwnd, MSG_PAINT,
|
|
// MAKELONG(DEC_BOX, LFRDR_BTN_STATUS_HILITE), 0);
|
|
ComboBoxDrawSpinButton(hwnd, 0, DEC_BOX, LFRDR_BTN_STATUS_HILITE);
|
|
mouse_old = DEC_BOX;
|
|
}
|
|
|
|
switch (dwStyle & CBS_TYPEMASK)
|
|
{
|
|
case CBS_SPINLIST:
|
|
if (IS_SET (pData, CSF_HASDROPPED)) {
|
|
SetFocusChild (pData->ListBoxControl);
|
|
}
|
|
case CBS_AUTOSPIN:
|
|
/* cancel repeat message */
|
|
SetAutoRepeatMessage (0, 0, 0, 0);
|
|
ReleaseCapture ();
|
|
}
|
|
NotifyParent (hwnd, pCtrl->id, CBN_CLICKED);
|
|
break;
|
|
}
|
|
|
|
case MSG_KEYDOWN:
|
|
{
|
|
switch (dwStyle & CBS_TYPEMASK) {
|
|
case CBS_SPINLIST:
|
|
case CBS_AUTOSPIN:
|
|
switch (LOWORD(wParam)) {
|
|
case SCANCODE_CURSORBLOCKUP:
|
|
case SCANCODE_CURSORBLOCKDOWN:
|
|
SendMessage (hwnd, CB_SPIN,
|
|
(LOWORD(wParam) == SCANCODE_CURSORBLOCKDOWN), 0);
|
|
break;
|
|
|
|
case SCANCODE_PAGEUP:
|
|
case SCANCODE_PAGEDOWN:
|
|
SendMessage (hwnd, CB_FASTSPIN,
|
|
(LOWORD(wParam) == SCANCODE_PAGEDOWN), 0);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case CBS_DROPDOWNLIST:
|
|
switch (LOWORD(wParam)) {
|
|
case SCANCODE_ESCAPE:
|
|
if (IS_SET (pData, CSF_HASDROPPED)) {
|
|
ShowWindow (pData->ListBoxControl, SW_HIDE);
|
|
CLEAR_STATE (pData, CSF_HASDROPPED);
|
|
if (dwStyle & CBS_NOTIFY) {
|
|
NotifyParent (hwnd, pCtrl->id, CBN_SELECTCANCEL);
|
|
NotifyParent (hwnd, pCtrl->id, CBN_CLOSEUP);
|
|
}
|
|
SetFocusChild (pData->EditControl);
|
|
}
|
|
break;
|
|
|
|
case SCANCODE_KEYPADENTER:
|
|
case SCANCODE_ENTER:
|
|
if (IS_SET (pData, CSF_HASDROPPED)) {
|
|
ShowWindow (pData->ListBoxControl, SW_HIDE);
|
|
CLEAR_STATE (pData, CSF_HASDROPPED);
|
|
if (dwStyle & CBS_NOTIFY) {
|
|
NotifyParent (hwnd, pCtrl->id, CBN_SELECTOK);
|
|
NotifyParent (hwnd, pCtrl->id, CBN_CLOSEUP);
|
|
}
|
|
SetFocusChild (pData->EditControl);
|
|
}
|
|
break;
|
|
|
|
case SCANCODE_CURSORBLOCKUP:
|
|
case SCANCODE_PAGEUP:
|
|
case SCANCODE_CURSORBLOCKDOWN:
|
|
case SCANCODE_PAGEDOWN:
|
|
if (!IS_SET (pData, CSF_HASDROPPED)) {
|
|
ShowWindow (pData->ListBoxControl, SW_SHOW);
|
|
SetFocusChild (pData->ListBoxControl);
|
|
SET_STATE (pData, CSF_HASDROPPED);
|
|
if (dwStyle & CBS_NOTIFY)
|
|
NotifyParent (hwnd, pCtrl->id, CBN_DROPDOWN);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
case MSG_COMMAND:
|
|
{
|
|
int len;
|
|
char *buffer;
|
|
int sel;
|
|
int id = LOWORD(wParam);
|
|
int code = HIWORD(wParam);
|
|
|
|
switch (id) {
|
|
case IDC_CLISTBOX:
|
|
{
|
|
if ((dwStyle & CBS_TYPEMASK) == CBS_DROPDOWNLIST &&
|
|
(code == LBN_CLICKED || code == LBN_KILLFOCUS)){
|
|
if (IS_SET (pData, CSF_HASDROPPED)) {
|
|
ShowWindow (pData->ListBoxControl, SW_HIDE);
|
|
CLEAR_STATE (pData, CSF_HASDROPPED);
|
|
if (dwStyle & CBS_NOTIFY) {
|
|
NotifyParent (hwnd, pCtrl->id, CBN_SELECTOK);
|
|
NotifyParent (hwnd, pCtrl->id, CBN_CLOSEUP);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (code == LBN_DBLCLK && (dwStyle & CBS_NOTIFY)) {
|
|
NotifyParent (hwnd, pCtrl->id, CBN_DBLCLK);
|
|
break;
|
|
}
|
|
|
|
if (code != LBN_SELCHANGE && dwStyle & CBS_READONLY)
|
|
break;
|
|
|
|
if ((sel = SendMessage (pData->ListBoxControl,
|
|
LB_GETCURSEL, 0, 0)) >= 0) {
|
|
len = SendMessage (pData->ListBoxControl, LB_GETTEXTLEN, sel, 0);
|
|
buffer = ALLOCATE_LOCAL (len + 1);
|
|
//buffer = FixStrAlloc (len + 1);
|
|
SendMessage (pData->ListBoxControl, LB_GETTEXT,
|
|
sel, (LPARAM)buffer);
|
|
SendMessage (pData->EditControl, MSG_SETTEXT, 0, (LPARAM)buffer);
|
|
DEALLOCATE_LOCAL(buffer);
|
|
//FreeFixStr (buffer);
|
|
}
|
|
|
|
if (dwStyle & CBS_NOTIFY)
|
|
NotifyParent (hwnd, pCtrl->id, CBN_SELCHANGE);
|
|
break;
|
|
}
|
|
|
|
case IDC_CEDIT:
|
|
if (code == EN_DBLCLK && dwStyle & CBS_NOTIFY) {
|
|
NotifyParent (hwnd, pCtrl->id, CBN_DBLCLK);
|
|
}
|
|
else if (code == EN_CLICKED) {
|
|
NotifyParent (hwnd, pCtrl->id, CBN_CLICKED);
|
|
}
|
|
else if (code == EN_CHANGE) {
|
|
if (GetFocusChild(hwnd) == pData->EditControl) {
|
|
if (pData->ListBoxControl) {
|
|
int len = GetWindowTextLength(pData->EditControl);
|
|
if ( len > 0) {
|
|
#ifdef HAVE_ALLOCA
|
|
char *str = (char*)alloca(len+1);
|
|
#else
|
|
char *str = (char*)malloc(len+1);
|
|
#endif
|
|
if(str){
|
|
GetWindowText (pData->EditControl, str, len);
|
|
if ((sel = SendMessage (pData->ListBoxControl,
|
|
LB_FINDSTRING, 0, (LPARAM)str)) >= 0)
|
|
SendMessage (pData->ListBoxControl,
|
|
LB_SETCURSEL, sel, 0);
|
|
#ifndef HAVE_ALLOCA
|
|
free(str);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dwStyle & CBS_NOTIFY)
|
|
NotifyParent (hwnd, pCtrl->id, CBN_EDITCHANGE);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case MSG_GETDLGCODE:
|
|
return DLGC_WANTARROWS | DLGC_WANTENTER;
|
|
|
|
case MSG_FONTCHANGED:
|
|
SetWindowFont (pData->EditControl, GetWindowFont (hwnd));
|
|
if (pData->ListBoxControl)
|
|
SetWindowFont (pData->ListBoxControl, GetWindowFont (hwnd));
|
|
return 0;
|
|
case MSG_MOUSEMOVEIN:
|
|
mouse_old = 0;
|
|
if(!(BOOL)wParam)
|
|
//SendMessage(hwnd, MSG_PAINT, 0, 0);
|
|
ComboBoxDrawSpinButton(hwnd, 0, 0, 0);
|
|
break;
|
|
case MSG_MOUSEMOVE:
|
|
{
|
|
int mouse = 0;
|
|
int x_pos = LOSWORD (lParam);
|
|
int y_pos = HISWORD (lParam);
|
|
|
|
if(PtInRect(&pData->IncSpinBox, x_pos, y_pos))
|
|
mouse = INC_BOX;
|
|
else if(PtInRect(&pData->DecSpinBox, x_pos, y_pos))
|
|
mouse = DEC_BOX;
|
|
else
|
|
mouse = 0;
|
|
|
|
if(mouse != mouse_old)
|
|
{
|
|
//SendMessage(hwnd, MSG_PAINT,
|
|
// MAKELONG(mouse, LFRDR_BTN_STATUS_HILITE), 0);
|
|
ComboBoxDrawSpinButton(hwnd, 0, mouse, LFRDR_BTN_STATUS_HILITE);
|
|
mouse_old = mouse;
|
|
}
|
|
break;
|
|
}
|
|
case MSG_PAINT:
|
|
{
|
|
HDC hdc;
|
|
hdc = BeginPaint (hwnd);
|
|
ComboBoxDrawSpinButton (hwnd, hdc, 0, 0);
|
|
EndPaint (hwnd, hdc);
|
|
return 0;
|
|
}
|
|
|
|
case CB_GETCHILDREN:
|
|
{
|
|
HWND* wnd_edit = (HWND*)wParam;
|
|
HWND* wnd_listbox = (HWND*)lParam;
|
|
|
|
*wnd_edit = pData->EditControl;
|
|
*wnd_listbox = pData->ListBoxControl;
|
|
return 0;
|
|
}
|
|
|
|
/* when click the up/down button,
|
|
* spin the value of SIMPLE and AUTOSPIN combobox */
|
|
case CB_SPIN:
|
|
switch (dwStyle & CBS_TYPEMASK) {
|
|
case CBS_SPINLIST:
|
|
if (wParam)
|
|
SendMessage (pData->ListBoxControl, MSG_KEYDOWN,
|
|
SCANCODE_CURSORBLOCKDOWN, 0);
|
|
else
|
|
SendMessage (pData->ListBoxControl, MSG_KEYDOWN,
|
|
SCANCODE_CURSORBLOCKUP, 0);
|
|
break;
|
|
|
|
case CBS_AUTOSPIN:
|
|
{
|
|
char buffer [LEN_SPINVALUE+1];
|
|
int cur_value = 0;
|
|
int new_value;
|
|
|
|
GetWindowText (pData->EditControl, buffer, LEN_SPINVALUE);
|
|
#if 0
|
|
cur_value = new_value = strtol (buffer, NULL, 0);
|
|
#else
|
|
sscanf (buffer, pData->str_format, &cur_value);
|
|
new_value = cur_value;
|
|
#endif
|
|
if (wParam) {
|
|
new_value -= pData->spin_pace;
|
|
}
|
|
else {
|
|
new_value += pData->spin_pace;
|
|
}
|
|
|
|
if (dwStyle & CBS_AUTOLOOP) {
|
|
if (new_value > pData->spin_max)
|
|
new_value = pData->spin_min;
|
|
else if (new_value < pData->spin_min)
|
|
new_value = pData->spin_max;
|
|
}
|
|
else {
|
|
if (new_value > pData->spin_max)
|
|
new_value = pData->spin_max;
|
|
else if (new_value < pData->spin_min)
|
|
new_value = pData->spin_min;
|
|
}
|
|
|
|
if (new_value != cur_value) {
|
|
snprintf (buffer, LEN_SPINVALUE, pData->str_format, new_value);
|
|
SetWindowText (pData->EditControl, buffer);
|
|
if (dwStyle & CBS_NOTIFY)
|
|
NotifyParent (hwnd, pCtrl->id, CBN_EDITCHANGE);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CB_FASTSPIN:
|
|
switch (dwStyle & CBS_TYPEMASK) {
|
|
case CBS_SPINLIST:
|
|
if (wParam)
|
|
SendMessage (pData->ListBoxControl, MSG_KEYDOWN,
|
|
SCANCODE_PAGEDOWN, 0);
|
|
else
|
|
SendMessage (pData->ListBoxControl, MSG_KEYDOWN,
|
|
SCANCODE_PAGEUP, 0);
|
|
break;
|
|
|
|
case CBS_AUTOSPIN:
|
|
{
|
|
char buffer [LEN_SPINVALUE+1];
|
|
int cur_value, new_value;
|
|
|
|
GetWindowText (pData->EditControl, buffer, LEN_SPINVALUE);
|
|
#if 0
|
|
cur_value = new_value = strtol (buffer, NULL, 0);
|
|
#else
|
|
sscanf (buffer, pData->str_format, &cur_value);
|
|
new_value = cur_value;
|
|
#endif
|
|
if (wParam) {
|
|
new_value -= pData->fastspin_pace;
|
|
}
|
|
else {
|
|
new_value += pData->fastspin_pace;
|
|
}
|
|
|
|
if (dwStyle & CBS_AUTOLOOP) {
|
|
if (new_value > pData->spin_max)
|
|
new_value = pData->spin_min;
|
|
else if (new_value < pData->spin_min)
|
|
new_value = pData->spin_max;
|
|
}
|
|
else {
|
|
if (new_value > pData->spin_max)
|
|
new_value = pData->spin_max;
|
|
else if (new_value < pData->spin_min)
|
|
new_value = pData->spin_min;
|
|
}
|
|
|
|
if (new_value != cur_value) {
|
|
snprintf (buffer, LEN_SPINVALUE, pData->str_format, new_value);
|
|
SetWindowText (pData->EditControl, buffer);
|
|
if (dwStyle & CBS_NOTIFY)
|
|
NotifyParent (hwnd, pCtrl->id, CBN_EDITCHANGE);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
break;
|
|
}
|
|
|
|
if ((dwStyle & CBS_TYPEMASK) == CBS_AUTOSPIN) {
|
|
switch (message) {
|
|
case CB_SETSPINFORMAT:
|
|
{
|
|
free (pData->str_format);
|
|
if ((pData->str_format = strdup ((const char*)lParam)))
|
|
return CB_OKAY;
|
|
|
|
return CB_ERR;
|
|
}
|
|
|
|
case CB_SETSPINRANGE:
|
|
{
|
|
char buffer [LEN_SPINVALUE+1];
|
|
int new_min = (int)wParam;
|
|
int new_max = (int)lParam;
|
|
int cur_value;
|
|
|
|
if (new_min > new_max)
|
|
return CB_ERR;
|
|
|
|
pData->spin_min = (int)wParam;
|
|
pData->spin_max = (int)lParam;
|
|
GetWindowText (pData->EditControl, buffer, LEN_SPINVALUE);
|
|
|
|
#if 0
|
|
cur_value = strtol (buffer, NULL, 0);
|
|
#else
|
|
sscanf (buffer, pData->str_format, &cur_value);
|
|
#endif
|
|
if (cur_value < pData->spin_min) {
|
|
snprintf (buffer, LEN_SPINVALUE,
|
|
pData->str_format, pData->spin_min);
|
|
SetWindowText (pData->EditControl, buffer);
|
|
}
|
|
else if (cur_value > pData->spin_max) {
|
|
snprintf (buffer, LEN_SPINVALUE,
|
|
pData->str_format, pData->spin_max);
|
|
SetWindowText (pData->EditControl, buffer);
|
|
}
|
|
|
|
return CB_OKAY;
|
|
}
|
|
|
|
case CB_GETSPINRANGE:
|
|
{
|
|
int* spin_min = (int*)wParam;
|
|
int* spin_max = (int*)lParam;
|
|
|
|
if (spin_min) *spin_min = pData->spin_min;
|
|
if (spin_max) *spin_max = pData->spin_max;
|
|
return CB_OKAY;
|
|
}
|
|
|
|
case CB_SETSPINVALUE:
|
|
{
|
|
int new_value = (int)wParam;
|
|
char buffer [LEN_SPINVALUE+1];
|
|
|
|
if (new_value < pData->spin_min || new_value > pData->spin_max)
|
|
return CB_ERR;
|
|
|
|
snprintf (buffer, LEN_SPINVALUE, pData->str_format, new_value);
|
|
SetWindowText (pData->EditControl, buffer);
|
|
return CB_OKAY;
|
|
}
|
|
|
|
case CB_GETSPINVALUE:
|
|
{
|
|
char buffer [LEN_SPINVALUE+1];
|
|
int value;
|
|
|
|
GetWindowText (pData->EditControl, buffer, LEN_SPINVALUE);
|
|
sscanf (buffer, pData->str_format, &value);
|
|
return value;
|
|
// return strtol (buffer, NULL, 0);
|
|
}
|
|
|
|
case CB_SETSPINPACE:
|
|
{
|
|
int pace = (int)wParam;
|
|
int fastpace = (int)lParam;
|
|
|
|
if (pace != 0)
|
|
pData->spin_pace = pace;
|
|
if (fastpace != 0)
|
|
pData->fastspin_pace = fastpace;
|
|
|
|
return CB_OKAY;
|
|
}
|
|
|
|
case CB_GETSPINPACE:
|
|
{
|
|
int *pace = (int*)wParam;
|
|
int *fastpace = (int*)lParam;
|
|
|
|
if (pace)
|
|
*pace = pData->spin_pace;
|
|
if (*fastpace)
|
|
*fastpace = pData->fastspin_pace;
|
|
|
|
return CB_OKAY;
|
|
}
|
|
}
|
|
return DefaultControlProc (hwnd, message, wParam, lParam);
|
|
}
|
|
else
|
|
return DefCBProc (hwnd, message, wParam, lParam);
|
|
}
|
|
|
|
static int DefCBProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PCOMBOBOXDATA pData;
|
|
int len, index;
|
|
char *selection;
|
|
int rc;
|
|
|
|
pData = (COMBOBOXDATA *) gui_Control(hWnd)->dwAddData2;
|
|
switch (message) {
|
|
/* messages specific to the listbox control */
|
|
case CB_SETSTRCMPFUNC:
|
|
return SendMessage (pData->ListBoxControl, LB_SETSTRCMPFUNC,
|
|
wParam, lParam);
|
|
|
|
case CB_ADDSTRING:
|
|
rc = SendMessage (pData->ListBoxControl, LB_ADDSTRING,
|
|
wParam, lParam);
|
|
if (rc >= 0)
|
|
pData->nListItems++;
|
|
return rc;
|
|
|
|
case CB_DELETESTRING:
|
|
rc = SendMessage (pData->ListBoxControl, LB_DELETESTRING,
|
|
wParam, lParam);
|
|
if (rc == 0) {
|
|
int idx;
|
|
pData->nListItems--;
|
|
if (pData->nListItems <= wParam)
|
|
idx = pData->nListItems - 1;
|
|
else
|
|
idx = wParam;
|
|
|
|
SendMessage (hWnd, CB_SETCURSEL, idx, 0);
|
|
}
|
|
return rc;
|
|
|
|
case CB_DIR:
|
|
return SendMessage (pData->ListBoxControl, LB_DIR, wParam, lParam);
|
|
|
|
case CB_FINDSTRING:
|
|
return SendMessage (pData->ListBoxControl, LB_FINDSTRING,
|
|
wParam, lParam);
|
|
|
|
case CB_FINDSTRINGEXACT:
|
|
return SendMessage (pData->ListBoxControl, LB_FINDSTRINGEXACT,
|
|
wParam, lParam);
|
|
|
|
case CB_GETCOUNT:
|
|
return SendMessage (pData->ListBoxControl, LB_GETCOUNT,
|
|
wParam, lParam);
|
|
|
|
case CB_GETITEMADDDATA:
|
|
return SendMessage (pData->ListBoxControl, LB_GETITEMADDDATA,
|
|
wParam, lParam);
|
|
|
|
case CB_SETITEMADDDATA:
|
|
return SendMessage (pData->ListBoxControl, LB_SETITEMADDDATA,
|
|
wParam, lParam);
|
|
|
|
case CB_GETITEMHEIGHT:
|
|
return SendMessage (pData->ListBoxControl, LB_GETITEMHEIGHT,
|
|
wParam, lParam);
|
|
|
|
case CB_SETITEMHEIGHT:
|
|
return SendMessage (pData->ListBoxControl, LB_SETITEMHEIGHT,
|
|
wParam, lParam);
|
|
|
|
case CB_GETLBTEXT:
|
|
return SendMessage (pData->ListBoxControl, LB_GETTEXT,
|
|
wParam, lParam);
|
|
|
|
case CB_GETLBTEXTLEN:
|
|
return SendMessage (pData->ListBoxControl, LB_GETTEXTLEN,
|
|
wParam, lParam);
|
|
|
|
case CB_INSERTSTRING:
|
|
rc = SendMessage (pData->ListBoxControl, LB_INSERTSTRING,
|
|
wParam, lParam);
|
|
if (rc >= 0)
|
|
pData->nListItems++;
|
|
return rc;
|
|
|
|
case CB_GETCURSEL:
|
|
return SendMessage (pData->ListBoxControl, LB_GETCURSEL,
|
|
wParam, lParam);
|
|
|
|
case CB_SETCURSEL:
|
|
if (SendMessage (pData->ListBoxControl, LB_SETCURSEL,
|
|
wParam, lParam) == LB_ERR) {
|
|
SetWindowText (pData->EditControl, "");
|
|
return CB_ERR;
|
|
}
|
|
|
|
index = SendMessage (pData->ListBoxControl, LB_GETCURSEL,
|
|
wParam, lParam);
|
|
len = SendMessage (pData->ListBoxControl, LB_GETTEXTLEN, index, 0);
|
|
if (len <= 0) {
|
|
SetWindowText (pData->EditControl, "");
|
|
return CB_ERR;
|
|
}
|
|
|
|
selection = FixStrAlloc (len + 1);
|
|
SendMessage (pData->ListBoxControl, LB_GETTEXT,
|
|
(WPARAM)index, (LPARAM)selection);
|
|
SetWindowText (pData->EditControl, selection);
|
|
FreeFixStr (selection);
|
|
break;
|
|
|
|
/* messages specific to the edit control */
|
|
case CB_GETEDITSEL:
|
|
return SendMessage (pData->EditControl, EM_GETSEL, wParam, lParam);
|
|
|
|
case CB_LIMITTEXT:
|
|
return SendMessage (pData->EditControl, EM_LIMITTEXT,
|
|
wParam, lParam);
|
|
|
|
case CB_SETEDITSEL:
|
|
return SendMessage (pData->EditControl, EM_SETSEL, wParam, lParam);
|
|
|
|
case MSG_GETTEXTLENGTH:
|
|
return SendMessage (pData->EditControl, MSG_GETTEXTLENGTH,
|
|
wParam, lParam);
|
|
|
|
case MSG_GETTEXT:
|
|
return SendMessage (pData->EditControl, MSG_GETTEXT, wParam, lParam);
|
|
|
|
case MSG_SETTEXT:
|
|
return SendMessage (pData->EditControl, MSG_SETTEXT, wParam, lParam);
|
|
|
|
/* messages handled by the combobox itself */
|
|
case CB_GETDROPPEDCONTROLRECT:
|
|
if (pData->ListBoxControl) {
|
|
CopyRect ((PRECT)lParam, &pData->ListBoxRect);
|
|
return 0;
|
|
}
|
|
return CB_ERR;
|
|
|
|
case CB_GETDROPPEDSTATE:
|
|
return IS_SET (pData, CSF_CAPTUREACTIVE);
|
|
|
|
case CB_RESETCONTENT:
|
|
SendMessage (pData->ListBoxControl, LB_RESETCONTENT, 0, 0);
|
|
SetWindowText (pData->EditControl, "");
|
|
return 0;
|
|
|
|
case CB_SELECTSTRING:
|
|
index = SendMessage (pData->ListBoxControl, LB_SELECTSTRING,
|
|
wParam, lParam);
|
|
if (index == LB_ERR)
|
|
return CB_ERR;
|
|
|
|
len = SendMessage (pData->ListBoxControl, LB_GETTEXTLEN, index, 0);
|
|
if (len <= 0)
|
|
return CB_ERR;
|
|
|
|
selection = FixStrAlloc (len + 1);
|
|
rc = SendMessage (pData->ListBoxControl, LB_GETTEXT,
|
|
(WPARAM)index, (LPARAM)selection);
|
|
SetWindowText (pData->EditControl, selection);
|
|
FreeFixStr (selection);
|
|
break;
|
|
}
|
|
|
|
return DefaultControlProc (hWnd, message, wParam, lParam);
|
|
}
|
|
|
|
#endif /* _MGCTRL_COMBOBOX */
|
|
|