[128] | 1 |
|
---|
| 2 | /*
|
---|
| 3 | *@@sourcefile cctl_combo.c:
|
---|
| 4 | * super combo box control, which is, essentially, a
|
---|
| 5 | * subclassed entry field with a list box attached to
|
---|
| 6 | * it.
|
---|
| 7 | *
|
---|
| 8 | * Compared to the standard PM combo box, this one has a
|
---|
| 9 | * number of advantages:
|
---|
| 10 | *
|
---|
| 11 | * -- It doesn't require the parent window to have the
|
---|
| 12 | * WS_CLIPCHILDREN style bit cleared.
|
---|
| 13 | *
|
---|
| 14 | * -- It has proper window positioning; the size of the
|
---|
| 15 | * enhanced combo is the size of the entry field, while
|
---|
| 16 | * the PM combo wants to have the size of the expanded
|
---|
| 17 | * list box too, which isn't easy to handle.
|
---|
| 18 | *
|
---|
| 19 | * See ctlComboFromEntryField for details.
|
---|
| 20 | *
|
---|
| 21 | * Note: Version numbering in this file relates to XWorkplace version
|
---|
| 22 | * numbering.
|
---|
| 23 | *
|
---|
| 24 | *@@header "helpers\comctl.h"
|
---|
| 25 | *@@added V0.9.16 (2002-01-01) [umoeller]
|
---|
| 26 | */
|
---|
| 27 |
|
---|
| 28 | /*
|
---|
| 29 | * Copyright (C) 2001-2002 Ulrich Mller.
|
---|
| 30 | * This file is part of the "XWorkplace helpers" source package.
|
---|
| 31 | * This is free software; you can redistribute it and/or modify
|
---|
| 32 | * it under the terms of the GNU General Public License as published
|
---|
| 33 | * by the Free Software Foundation, in version 2 as it comes in the
|
---|
| 34 | * "COPYING" file of the XWorkplace main distribution.
|
---|
| 35 | * This program is distributed in the hope that it will be useful,
|
---|
| 36 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 37 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 38 | * GNU General Public License for more details.
|
---|
| 39 | */
|
---|
| 40 |
|
---|
| 41 | #define OS2EMX_PLAIN_CHAR
|
---|
| 42 | // this is needed for "os2emx.h"; if this is defined,
|
---|
| 43 | // emx will define PSZ as _signed_ char, otherwise
|
---|
| 44 | // as unsigned char
|
---|
| 45 |
|
---|
| 46 | #define INCL_DOSEXCEPTIONS
|
---|
| 47 | #define INCL_DOSPROCESS
|
---|
| 48 | #define INCL_DOSSEMAPHORES
|
---|
| 49 | #define INCL_DOSERRORS
|
---|
| 50 |
|
---|
| 51 | #define INCL_WINWINDOWMGR
|
---|
| 52 | #define INCL_WINFRAMEMGR
|
---|
| 53 | #define INCL_WININPUT
|
---|
| 54 | #define INCL_WINPOINTERS
|
---|
| 55 |
|
---|
| 56 | #define INCL_WINBUTTONS
|
---|
| 57 | #define INCL_WINENTRYFIELDS
|
---|
| 58 | #define INCL_WINLISTBOXES
|
---|
| 59 |
|
---|
| 60 | #define INCL_GPILOGCOLORTABLE
|
---|
| 61 | #define INCL_GPIBITMAPS
|
---|
| 62 | #include <os2.h>
|
---|
| 63 |
|
---|
| 64 | #include <stdlib.h>
|
---|
| 65 | #include <stdio.h>
|
---|
| 66 | #include <string.h>
|
---|
| 67 | #include <setjmp.h> // needed for except.h
|
---|
| 68 | #include <assert.h> // needed for except.h
|
---|
| 69 |
|
---|
| 70 | #include "setup.h" // code generation and debugging options
|
---|
| 71 |
|
---|
| 72 | #include "helpers\except.h" // exception handling
|
---|
| 73 | #include "helpers\winh.h"
|
---|
| 74 |
|
---|
| 75 | #include "helpers\comctl.h"
|
---|
| 76 |
|
---|
| 77 | #pragma hdrstop
|
---|
| 78 |
|
---|
| 79 | /*
|
---|
| 80 | *@@category: Helpers\PM helpers\Window classes\Super combo box
|
---|
| 81 | * See cctl_combo.c.
|
---|
| 82 | */
|
---|
| 83 |
|
---|
| 84 | /* ******************************************************************
|
---|
| 85 | *
|
---|
| 86 | * Super Combination Box control
|
---|
| 87 | *
|
---|
| 88 | ********************************************************************/
|
---|
| 89 |
|
---|
| 90 | #define COMBO_BUTTON_WIDTH 20
|
---|
| 91 |
|
---|
| 92 | #define ID_COMBO_BUTTON 1001
|
---|
| 93 | #define ID_COMBO_LISTBOX 1002
|
---|
| 94 |
|
---|
| 95 | /*
|
---|
| 96 | *@@ COMBODATA:
|
---|
| 97 | *
|
---|
| 98 | *@@added V0.9.9 (2001-03-17) [umoeller]
|
---|
| 99 | */
|
---|
| 100 |
|
---|
| 101 | typedef struct _COMBODATA
|
---|
| 102 | {
|
---|
| 103 | PFNWP pfnwpOrigEntryField,
|
---|
| 104 | pfnwpOrigButton;
|
---|
| 105 | ULONG flStyle;
|
---|
| 106 |
|
---|
| 107 | // position of entire combo
|
---|
| 108 | LONG x,
|
---|
| 109 | y,
|
---|
| 110 | cx,
|
---|
| 111 | cy;
|
---|
| 112 |
|
---|
| 113 | HWND hwndButton,
|
---|
| 114 | hwndListbox;
|
---|
| 115 |
|
---|
| 116 | HBITMAP hbmButton;
|
---|
| 117 | SIZEL szlButton; // bitmap dimensions
|
---|
| 118 |
|
---|
| 119 | } COMBODATA, *PCOMBODATA;
|
---|
| 120 |
|
---|
| 121 | /*
|
---|
| 122 | *@@ PaintButtonBitmap:
|
---|
| 123 | *
|
---|
| 124 | *@@added V0.9.9 (2001-03-17) [umoeller]
|
---|
| 125 | */
|
---|
| 126 |
|
---|
[222] | 127 | STATIC VOID PaintButtonBitmap(HWND hwnd,
|
---|
[142] | 128 | PCOMBODATA pcd)
|
---|
[128] | 129 | {
|
---|
| 130 | HPS hps;
|
---|
| 131 | RECTL rcl;
|
---|
| 132 | POINTL ptlDest;
|
---|
| 133 |
|
---|
| 134 | hps = WinGetPS(hwnd);
|
---|
| 135 | WinQueryWindowRect(hwnd, &rcl);
|
---|
| 136 |
|
---|
| 137 | ptlDest.x = (rcl.xRight - pcd->szlButton.cx) / 2;
|
---|
| 138 | ptlDest.y = (rcl.yTop - pcd->szlButton.cy) / 2;
|
---|
| 139 | WinDrawBitmap(hps,
|
---|
| 140 | pcd->hbmButton,
|
---|
| 141 | NULL,
|
---|
| 142 | &ptlDest,
|
---|
| 143 | 0, 0,
|
---|
| 144 | DBM_NORMAL);
|
---|
| 145 |
|
---|
| 146 | WinReleasePS(hps);
|
---|
| 147 | }
|
---|
| 148 |
|
---|
| 149 | /*
|
---|
| 150 | *@@ fnwpSubclassedComboButton:
|
---|
| 151 | * window proc the combobox's button is subclassed with.
|
---|
| 152 | * This is only for WM_PAINT because BN_PAINT is really
|
---|
| 153 | * not that great for painting a button that looks like
|
---|
| 154 | * a standard button.
|
---|
| 155 | *
|
---|
| 156 | *@@added V0.9.9 (2001-03-17) [umoeller]
|
---|
| 157 | */
|
---|
| 158 |
|
---|
[222] | 159 | STATIC MRESULT EXPENTRY fnwpSubclassedComboButton(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
---|
[128] | 160 | {
|
---|
| 161 | MRESULT mrc = 0;
|
---|
| 162 | PCOMBODATA pcd;
|
---|
| 163 |
|
---|
| 164 | switch (msg)
|
---|
| 165 | {
|
---|
| 166 | case WM_PAINT:
|
---|
| 167 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 168 | {
|
---|
| 169 | mrc = pcd->pfnwpOrigButton(hwnd, msg, mp1, mp2);
|
---|
| 170 |
|
---|
| 171 | PaintButtonBitmap(hwnd, pcd);
|
---|
| 172 | }
|
---|
| 173 | break;
|
---|
| 174 |
|
---|
| 175 | /*
|
---|
| 176 | * default:
|
---|
| 177 | *
|
---|
| 178 | */
|
---|
| 179 |
|
---|
| 180 | default:
|
---|
| 181 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 182 | mrc = pcd->pfnwpOrigButton(hwnd, msg, mp1, mp2);
|
---|
| 183 | break;
|
---|
| 184 | }
|
---|
| 185 |
|
---|
[167] | 186 | return mrc;
|
---|
[128] | 187 | }
|
---|
| 188 |
|
---|
| 189 | /*
|
---|
| 190 | *@@ ShowListbox:
|
---|
| 191 | *
|
---|
| 192 | *@@added V0.9.9 (2001-03-17) [umoeller]
|
---|
| 193 | */
|
---|
| 194 |
|
---|
[222] | 195 | STATIC VOID ShowListbox(HWND hwnd, // in: subclassed entry field
|
---|
[142] | 196 | PCOMBODATA pcd,
|
---|
| 197 | BOOL fShow) // in: TRUE == show, FALSE == hide
|
---|
[128] | 198 | {
|
---|
| 199 | BOOL fHilite = FALSE;
|
---|
| 200 |
|
---|
| 201 | if (fShow)
|
---|
| 202 | {
|
---|
| 203 | // list box is invisible:
|
---|
| 204 | SWP swp;
|
---|
| 205 | POINTL ptl;
|
---|
| 206 | WinQueryWindowPos(hwnd, &swp);
|
---|
| 207 |
|
---|
| 208 | _Pmpf(("showing lb"));
|
---|
| 209 |
|
---|
| 210 | // convert to desktop
|
---|
| 211 | ptl.x = swp.x;
|
---|
| 212 | ptl.y = swp.y;
|
---|
| 213 | WinMapWindowPoints(WinQueryWindow(hwnd, QW_PARENT), // from
|
---|
| 214 | HWND_DESKTOP, // to
|
---|
| 215 | &ptl,
|
---|
| 216 | // SWP.y comes before SWP.x
|
---|
| 217 | 1);
|
---|
| 218 |
|
---|
| 219 | WinSetWindowPos(pcd->hwndListbox,
|
---|
| 220 | HWND_TOP,
|
---|
| 221 | ptl.x + COMBO_BUTTON_WIDTH,
|
---|
| 222 | ptl.y - 100,
|
---|
| 223 | swp.cx,
|
---|
| 224 | 100,
|
---|
| 225 | SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_NOREDRAW);
|
---|
| 226 | WinSetParent(pcd->hwndListbox,
|
---|
| 227 | HWND_DESKTOP,
|
---|
| 228 | TRUE); // redraw
|
---|
| 229 |
|
---|
| 230 | // set focus to subclassed entry field in any case;
|
---|
| 231 | // we never let the listbox get the focus
|
---|
| 232 | WinSetFocus(HWND_DESKTOP, hwnd);
|
---|
| 233 |
|
---|
| 234 | fHilite = TRUE;
|
---|
| 235 | }
|
---|
| 236 | else
|
---|
| 237 | {
|
---|
| 238 | // list box is showing:
|
---|
| 239 | HWND hwndFocus = WinQueryFocus(HWND_DESKTOP);
|
---|
| 240 | _Pmpf(("hiding listbox"));
|
---|
| 241 |
|
---|
| 242 | WinSetParent(pcd->hwndListbox,
|
---|
| 243 | HWND_OBJECT,
|
---|
| 244 | TRUE); // redraw now
|
---|
| 245 | // give focus back to entry field
|
---|
| 246 | if (hwndFocus == pcd->hwndListbox)
|
---|
| 247 | WinSetFocus(HWND_DESKTOP, hwnd);
|
---|
| 248 | }
|
---|
| 249 |
|
---|
| 250 | WinSendMsg(pcd->hwndButton,
|
---|
| 251 | BM_SETHILITE,
|
---|
| 252 | (MPARAM)fHilite,
|
---|
| 253 | 0);
|
---|
| 254 | PaintButtonBitmap(pcd->hwndButton, pcd);
|
---|
| 255 | }
|
---|
| 256 |
|
---|
| 257 | /*
|
---|
| 258 | *@@ fnwpComboSubclass:
|
---|
| 259 | *
|
---|
| 260 | *@@added V0.9.9 (2001-03-17) [umoeller]
|
---|
| 261 | */
|
---|
| 262 |
|
---|
[222] | 263 | STATIC MRESULT EXPENTRY fnwpComboSubclass(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
---|
[128] | 264 | {
|
---|
| 265 | MRESULT mrc = 0;
|
---|
| 266 | PCOMBODATA pcd;
|
---|
| 267 |
|
---|
| 268 | switch (msg)
|
---|
| 269 | {
|
---|
| 270 | /*
|
---|
| 271 | * WM_ADJUSTWINDOWPOS:
|
---|
| 272 | *
|
---|
| 273 | */
|
---|
| 274 |
|
---|
| 275 | case WM_ADJUSTWINDOWPOS:
|
---|
| 276 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 277 | {
|
---|
| 278 | PSWP pswp = (PSWP)mp1;
|
---|
| 279 |
|
---|
| 280 | if (pswp->fl & SWP_SIZE)
|
---|
| 281 | // if we're being sized, make us smaller so that
|
---|
| 282 | // there's room for the button
|
---|
| 283 | pswp->cx -= COMBO_BUTTON_WIDTH;
|
---|
| 284 |
|
---|
| 285 | mrc = pcd->pfnwpOrigEntryField(hwnd, msg, mp1, mp2);
|
---|
| 286 | }
|
---|
| 287 | break;
|
---|
| 288 |
|
---|
| 289 | /*
|
---|
| 290 | * WM_WINDOWPOSCHANGED:
|
---|
| 291 | *
|
---|
| 292 | */
|
---|
| 293 |
|
---|
| 294 | case WM_WINDOWPOSCHANGED:
|
---|
| 295 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 296 | {
|
---|
| 297 | PSWP pswpNew = (PSWP)mp1;
|
---|
| 298 |
|
---|
| 299 | if (pswpNew->fl & (SWP_SIZE | SWP_MOVE))
|
---|
| 300 | {
|
---|
| 301 | // moved or sized:
|
---|
| 302 | SWP swp;
|
---|
| 303 | WinQueryWindowPos(hwnd, &swp);
|
---|
| 304 | WinSetWindowPos(pcd->hwndButton,
|
---|
| 305 | 0,
|
---|
| 306 | pswpNew->x + pswpNew->cx, // has already been truncated!
|
---|
| 307 | pswpNew->y,
|
---|
| 308 | COMBO_BUTTON_WIDTH,
|
---|
| 309 | pswpNew->cy,
|
---|
| 310 | SWP_MOVE | SWP_SIZE);
|
---|
| 311 | }
|
---|
| 312 |
|
---|
| 313 | mrc = pcd->pfnwpOrigEntryField(hwnd, msg, mp1, mp2);
|
---|
| 314 | }
|
---|
| 315 | break;
|
---|
| 316 |
|
---|
| 317 | /*
|
---|
| 318 | * WM_SETFOCUS:
|
---|
| 319 | * hide listbox if focus is going away from us
|
---|
| 320 | */
|
---|
| 321 |
|
---|
| 322 | case WM_SETFOCUS:
|
---|
| 323 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 324 | {
|
---|
| 325 | if (!mp2)
|
---|
| 326 | // we're losing focus:
|
---|
| 327 | // is listbox currently showing?
|
---|
| 328 | ShowListbox(hwnd,
|
---|
| 329 | pcd,
|
---|
| 330 | FALSE);
|
---|
| 331 |
|
---|
| 332 | mrc = pcd->pfnwpOrigEntryField(hwnd, msg, mp1, mp2);
|
---|
| 333 | }
|
---|
| 334 | break;
|
---|
| 335 |
|
---|
| 336 | /*
|
---|
| 337 | * WM_COMMAND:
|
---|
| 338 | * show/hide listbox if the button gets pressed.
|
---|
| 339 | */
|
---|
| 340 |
|
---|
| 341 | case WM_COMMAND:
|
---|
| 342 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 343 | {
|
---|
| 344 | if (SHORT1FROMMP(mp1) == ID_COMBO_BUTTON)
|
---|
| 345 | {
|
---|
| 346 | // button clicked:
|
---|
| 347 | ShowListbox(hwnd,
|
---|
| 348 | pcd,
|
---|
| 349 | // check state of list box
|
---|
| 350 | (WinQueryWindow(pcd->hwndListbox, QW_PARENT)
|
---|
| 351 | == WinQueryObjectWindow(HWND_DESKTOP)));
|
---|
| 352 |
|
---|
| 353 | // do not call parent
|
---|
| 354 | break;
|
---|
| 355 |
|
---|
| 356 | } // end if ((SHORT)mp1 == ID_COMBO_BUTTON)
|
---|
| 357 |
|
---|
| 358 | mrc = pcd->pfnwpOrigEntryField(hwnd, msg, mp1, mp2);
|
---|
| 359 | }
|
---|
| 360 | break;
|
---|
| 361 |
|
---|
| 362 | /*
|
---|
| 363 | * WM_CONTROL:
|
---|
| 364 | * handle notifications from listbox.
|
---|
| 365 | */
|
---|
| 366 |
|
---|
| 367 | case WM_CONTROL:
|
---|
| 368 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 369 | {
|
---|
| 370 | USHORT usid = SHORT1FROMMP(mp1),
|
---|
| 371 | uscode = SHORT2FROMMP(mp1);
|
---|
| 372 | if (usid == ID_COMBO_LISTBOX)
|
---|
| 373 | {
|
---|
| 374 | switch (uscode)
|
---|
| 375 | {
|
---|
| 376 | case LN_ENTER:
|
---|
| 377 | break;
|
---|
| 378 |
|
---|
| 379 | case LN_SELECT:
|
---|
| 380 | {
|
---|
| 381 | SHORT sSelected = winhQueryLboxSelectedItem(pcd->hwndListbox,
|
---|
| 382 | LIT_FIRST);
|
---|
| 383 | PSZ psz = NULL;
|
---|
| 384 | if (sSelected != LIT_NONE)
|
---|
| 385 | {
|
---|
| 386 | psz = winhQueryLboxItemText(pcd->hwndListbox,
|
---|
| 387 | sSelected);
|
---|
| 388 | }
|
---|
| 389 | WinSetWindowText(hwnd, psz);
|
---|
| 390 | if (psz)
|
---|
| 391 | {
|
---|
| 392 | WinPostMsg(hwnd,
|
---|
| 393 | EM_SETSEL,
|
---|
| 394 | MPFROM2SHORT(0, strlen(psz)),
|
---|
| 395 | 0);
|
---|
| 396 | free(psz);
|
---|
| 397 | }
|
---|
| 398 | break; }
|
---|
| 399 |
|
---|
| 400 | case LN_SETFOCUS:
|
---|
| 401 | // when the list box gets the focus, always
|
---|
| 402 | // set focus to ourselves
|
---|
| 403 | WinSetFocus(HWND_DESKTOP, hwnd);
|
---|
| 404 | break;
|
---|
| 405 | }
|
---|
| 406 |
|
---|
| 407 | // forward list box notifications to
|
---|
| 408 | // our own owner, but replace the id
|
---|
| 409 | // with the combo box id
|
---|
[232] | 410 | ctlPostWmControl(hwnd,
|
---|
| 411 | uscode,
|
---|
| 412 | mp2);
|
---|
[128] | 413 |
|
---|
| 414 | // do not call parent
|
---|
| 415 | break;
|
---|
| 416 |
|
---|
| 417 | } // end if (usid == ID_COMBO_LISTBOX)
|
---|
| 418 |
|
---|
| 419 | mrc = pcd->pfnwpOrigEntryField(hwnd, msg, mp1, mp2);
|
---|
| 420 | }
|
---|
| 421 | break;
|
---|
| 422 |
|
---|
| 423 | /*
|
---|
| 424 | * WM_CHAR:
|
---|
| 425 | *
|
---|
| 426 | */
|
---|
| 427 |
|
---|
| 428 | case WM_CHAR:
|
---|
| 429 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 430 | {
|
---|
| 431 | USHORT usFlags = SHORT1FROMMP(mp1);
|
---|
| 432 | // USHORT usch = SHORT1FROMMP(mp2);
|
---|
| 433 | USHORT usvk = SHORT2FROMMP(mp2);
|
---|
| 434 |
|
---|
| 435 | if ((usFlags & KC_KEYUP) == 0)
|
---|
| 436 | {
|
---|
| 437 | if (usFlags & KC_VIRTUALKEY)
|
---|
| 438 | {
|
---|
| 439 | switch (usvk)
|
---|
| 440 | {
|
---|
| 441 | case VK_DOWN:
|
---|
| 442 | case VK_UP:
|
---|
| 443 | // if alt is pressed with these, show/hide listbox
|
---|
| 444 | if (usFlags & KC_ALT)
|
---|
| 445 | WinPostMsg(hwnd,
|
---|
| 446 | CBM_SHOWLIST,
|
---|
| 447 | (MPARAM)(WinQueryWindow(pcd->hwndListbox, QW_PARENT)
|
---|
| 448 | == WinQueryObjectWindow(HWND_DESKTOP)),
|
---|
| 449 | 0);
|
---|
| 450 | else
|
---|
| 451 | {
|
---|
| 452 | // just up or down, no alt:
|
---|
| 453 | // select next or previous item in list box
|
---|
| 454 | SHORT sSelected = winhQueryLboxSelectedItem(pcd->hwndListbox,
|
---|
| 455 | LIT_FIRST),
|
---|
| 456 | sNew = 0;
|
---|
| 457 |
|
---|
| 458 | if (usvk == VK_DOWN)
|
---|
| 459 | {
|
---|
| 460 | if (sSelected != LIT_NONE)
|
---|
| 461 | {
|
---|
| 462 | if (sSelected < WinQueryLboxCount(pcd->hwndListbox))
|
---|
| 463 | sNew = sSelected + 1;
|
---|
| 464 | }
|
---|
| 465 | // else: sNew still 0
|
---|
| 466 | }
|
---|
| 467 | else
|
---|
| 468 | {
|
---|
| 469 | // up:
|
---|
| 470 | if ( (sSelected != LIT_NONE)
|
---|
| 471 | && (sSelected > 0)
|
---|
| 472 | )
|
---|
| 473 | sNew = sSelected - 1;
|
---|
| 474 | }
|
---|
| 475 |
|
---|
| 476 | winhSetLboxSelectedItem(pcd->hwndListbox,
|
---|
| 477 | sNew,
|
---|
| 478 | TRUE);
|
---|
| 479 | }
|
---|
| 480 | break;
|
---|
| 481 | }
|
---|
| 482 | }
|
---|
| 483 | }
|
---|
| 484 |
|
---|
| 485 | // call parent only if this is not a drop-down list
|
---|
| 486 | if ((pcd->flStyle & CBS_DROPDOWNLIST) == 0)
|
---|
| 487 | mrc = pcd->pfnwpOrigEntryField(hwnd, msg, mp1, mp2);
|
---|
| 488 | else
|
---|
| 489 | // forward to owner
|
---|
| 490 | WinSendMsg(WinQueryWindow(hwnd, QW_OWNER),
|
---|
| 491 | msg,
|
---|
| 492 | mp1,
|
---|
| 493 | mp2);
|
---|
| 494 | }
|
---|
| 495 | break;
|
---|
| 496 |
|
---|
| 497 | /*
|
---|
| 498 | * CBM_ISLISTSHOWING:
|
---|
| 499 | * implementation of the original combobox msg.
|
---|
| 500 | */
|
---|
| 501 |
|
---|
| 502 | case CBM_ISLISTSHOWING:
|
---|
| 503 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 504 | {
|
---|
| 505 | mrc = (MPARAM)(WinQueryWindow(pcd->hwndListbox, QW_PARENT)
|
---|
| 506 | == WinQueryObjectWindow(HWND_DESKTOP));
|
---|
| 507 | }
|
---|
| 508 | break;
|
---|
| 509 |
|
---|
| 510 | /*
|
---|
| 511 | * CBM_SHOWLIST:
|
---|
| 512 | * implementation of the original combobox msg.
|
---|
| 513 | */
|
---|
| 514 |
|
---|
| 515 | case CBM_SHOWLIST:
|
---|
| 516 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 517 | {
|
---|
| 518 | ShowListbox(hwnd,
|
---|
| 519 | pcd,
|
---|
| 520 | (BOOL)mp1);
|
---|
| 521 | }
|
---|
| 522 | break;
|
---|
| 523 |
|
---|
| 524 | /*
|
---|
| 525 | * list box messages:
|
---|
| 526 | * forward all these to the listbox and
|
---|
| 527 | * return the listbox return value.
|
---|
| 528 | */
|
---|
| 529 |
|
---|
| 530 | case LM_INSERTITEM:
|
---|
| 531 | case LM_SETTOPINDEX:
|
---|
| 532 | case LM_QUERYTOPINDEX:
|
---|
| 533 | case LM_DELETEITEM:
|
---|
| 534 | case LM_SELECTITEM:
|
---|
| 535 | case LM_QUERYSELECTION:
|
---|
| 536 | case LM_SETITEMTEXT:
|
---|
| 537 | case LM_QUERYITEMTEXT:
|
---|
| 538 | case LM_SEARCHSTRING:
|
---|
| 539 | case LM_DELETEALL:
|
---|
| 540 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 541 | mrc = WinSendMsg(pcd->hwndListbox, msg, mp1, mp2);
|
---|
| 542 | break;
|
---|
| 543 |
|
---|
| 544 | /*
|
---|
| 545 | * WM_DESTROY:
|
---|
| 546 | *
|
---|
| 547 | */
|
---|
| 548 |
|
---|
| 549 | case WM_DESTROY:
|
---|
| 550 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 551 | {
|
---|
| 552 | WinDestroyWindow(pcd->hwndButton);
|
---|
| 553 | WinDestroyWindow(pcd->hwndListbox);
|
---|
| 554 |
|
---|
| 555 | mrc = pcd->pfnwpOrigEntryField(hwnd, msg, mp1, mp2);
|
---|
| 556 |
|
---|
| 557 | free(pcd);
|
---|
| 558 | }
|
---|
| 559 | break;
|
---|
| 560 |
|
---|
| 561 | /*
|
---|
| 562 | * default:
|
---|
| 563 | *
|
---|
| 564 | */
|
---|
| 565 |
|
---|
| 566 | default:
|
---|
| 567 | if (pcd = (PCOMBODATA)WinQueryWindowPtr(hwnd, QWL_USER))
|
---|
| 568 | mrc = pcd->pfnwpOrigEntryField(hwnd, msg, mp1, mp2);
|
---|
| 569 | break;
|
---|
| 570 | }
|
---|
| 571 |
|
---|
[167] | 572 | return mrc;
|
---|
[128] | 573 | }
|
---|
| 574 |
|
---|
| 575 | /*
|
---|
| 576 | *@@ ctlComboFromEntryField:
|
---|
| 577 | * turns a standard entry field control into an
|
---|
| 578 | * XComboBox.
|
---|
| 579 | *
|
---|
| 580 | * The XComboBox is intended to work like a standard
|
---|
| 581 | * combobox, but it doesn't have the silly limitation
|
---|
| 582 | * that the size of the combobox is assumed to be
|
---|
| 583 | * the size of the dropped-down combobox. This limitation
|
---|
| 584 | * makes it impossible to use standard comboboxes in
|
---|
| 585 | * windows which have the WS_CLIPCHILDREN style because
|
---|
| 586 | * the entire combo area will always be clipped out.
|
---|
| 587 | *
|
---|
| 588 | * This is not a full reimplementation. Only drop-down
|
---|
| 589 | * and drop-down list comboboxes are supported. Besides,
|
---|
| 590 | * the XComboBox is essentially a subclassed entryfield,
|
---|
| 591 | * so there might be limitations.
|
---|
| 592 | *
|
---|
| 593 | * On input to this function, with flStyle, specify
|
---|
| 594 | * either CBS_DROPDOWN or CBS_DROPDOWNLIST. CBS_SIMPLE
|
---|
| 595 | * is not supported.
|
---|
| 596 | *
|
---|
| 597 | * Supported messages to the XComboBox after this funcion
|
---|
| 598 | * has been called:
|
---|
| 599 | *
|
---|
| 600 | * -- CBM_ISLISTSHOWING
|
---|
| 601 | *
|
---|
| 602 | * -- CBM_SHOWLIST
|
---|
| 603 | *
|
---|
| 604 | * -- LM_QUERYITEMCOUNT
|
---|
| 605 | *
|
---|
| 606 | * -- LM_INSERTITEM
|
---|
| 607 | *
|
---|
| 608 | * -- LM_SETTOPINDEX
|
---|
| 609 | *
|
---|
| 610 | * -- LM_QUERYTOPINDEX
|
---|
| 611 | *
|
---|
| 612 | * -- LM_DELETEITEM
|
---|
| 613 | *
|
---|
| 614 | * -- LM_SELECTITEM
|
---|
| 615 | *
|
---|
| 616 | * -- LM_QUERYSELECTION
|
---|
| 617 | *
|
---|
| 618 | * -- LM_SETITEMTEXT
|
---|
| 619 | *
|
---|
| 620 | * -- LM_QUERYITEMTEXT
|
---|
| 621 | *
|
---|
| 622 | * -- LM_SEARCHSTRING
|
---|
| 623 | *
|
---|
| 624 | * -- LM_DELETEALL
|
---|
| 625 | *
|
---|
| 626 | * NOTE: This occupies QWL_USER of the entryfield.
|
---|
| 627 | *
|
---|
| 628 | *@@added V0.9.9 (2001-03-17) [umoeller]
|
---|
| 629 | */
|
---|
| 630 |
|
---|
| 631 | BOOL ctlComboFromEntryField(HWND hwnd, // in: entry field to be converted
|
---|
| 632 | ULONG flStyle) // in: combo box styles
|
---|
| 633 | {
|
---|
| 634 | BOOL brc = FALSE;
|
---|
| 635 | PFNWP pfnwpOrig;
|
---|
| 636 | if (pfnwpOrig = WinSubclassWindow(hwnd,
|
---|
| 637 | fnwpComboSubclass))
|
---|
| 638 | {
|
---|
| 639 | PCOMBODATA pcd;
|
---|
| 640 | if (pcd = (PCOMBODATA)malloc(sizeof(*pcd)))
|
---|
| 641 | {
|
---|
| 642 | SWP swp;
|
---|
| 643 | BITMAPINFOHEADER2 bmih2;
|
---|
| 644 |
|
---|
| 645 | memset(pcd, 0, sizeof(*pcd));
|
---|
| 646 | pcd->pfnwpOrigEntryField = pfnwpOrig;
|
---|
| 647 | pcd->flStyle = flStyle;
|
---|
| 648 |
|
---|
| 649 | WinSetWindowPtr(hwnd, QWL_USER, pcd);
|
---|
| 650 |
|
---|
| 651 | WinQueryWindowPos(hwnd, &swp);
|
---|
| 652 | pcd->x = swp.x;
|
---|
| 653 | pcd->y = swp.y;
|
---|
| 654 | pcd->cx = swp.cx;
|
---|
| 655 | pcd->cy = swp.cy;
|
---|
| 656 |
|
---|
| 657 | swp.cx -= COMBO_BUTTON_WIDTH;
|
---|
| 658 | WinSetWindowPos(hwnd,
|
---|
| 659 | 0,
|
---|
| 660 | 0, 0,
|
---|
| 661 | swp.cx, swp.cy,
|
---|
| 662 | SWP_SIZE | SWP_NOADJUST); // circumvent subclassing
|
---|
| 663 |
|
---|
| 664 | pcd->hbmButton = WinGetSysBitmap(HWND_DESKTOP,
|
---|
| 665 | SBMP_COMBODOWN);
|
---|
| 666 | bmih2.cbFix = sizeof(bmih2);
|
---|
| 667 | GpiQueryBitmapInfoHeader(pcd->hbmButton,
|
---|
| 668 | &bmih2);
|
---|
| 669 | pcd->szlButton.cx = bmih2.cx;
|
---|
| 670 | pcd->szlButton.cy = bmih2.cy;
|
---|
| 671 |
|
---|
| 672 | pcd->hwndButton = WinCreateWindow(WinQueryWindow(hwnd, QW_PARENT),
|
---|
| 673 | WC_BUTTON,
|
---|
| 674 | "",
|
---|
| 675 | WS_VISIBLE
|
---|
| 676 | | BS_PUSHBUTTON | BS_NOPOINTERFOCUS,
|
---|
| 677 | swp.x + swp.cx - COMBO_BUTTON_WIDTH,
|
---|
| 678 | swp.y,
|
---|
| 679 | COMBO_BUTTON_WIDTH,
|
---|
| 680 | swp.cy,
|
---|
| 681 | hwnd, // owner == entry field!
|
---|
| 682 | hwnd, // insert behind entry field
|
---|
| 683 | ID_COMBO_BUTTON,
|
---|
| 684 | NULL,
|
---|
| 685 | NULL);
|
---|
| 686 | WinSetWindowPtr(pcd->hwndButton, QWL_USER, pcd);
|
---|
| 687 | pcd->pfnwpOrigButton = WinSubclassWindow(pcd->hwndButton,
|
---|
| 688 | fnwpSubclassedComboButton);
|
---|
| 689 |
|
---|
| 690 | pcd->hwndListbox = WinCreateWindow(HWND_OBJECT, // parent, for now
|
---|
| 691 | WC_LISTBOX,
|
---|
| 692 | "?",
|
---|
| 693 | WS_VISIBLE | WS_SAVEBITS | WS_CLIPSIBLINGS
|
---|
| 694 | | LS_NOADJUSTPOS,
|
---|
| 695 | 0,
|
---|
| 696 | 0,
|
---|
| 697 | 0,
|
---|
| 698 | 0,
|
---|
| 699 | hwnd, // owner == entry field!
|
---|
| 700 | HWND_TOP, // insert behind entry field
|
---|
| 701 | ID_COMBO_LISTBOX,
|
---|
| 702 | NULL,
|
---|
| 703 | NULL);
|
---|
| 704 |
|
---|
| 705 | // finally, set style of entry field... we force
|
---|
| 706 | // these flags no matter what the original style
|
---|
| 707 | // was
|
---|
| 708 | /* WinSetWindowBits(hwnd,
|
---|
| 709 | QWL_STYLE,
|
---|
| 710 | // bits to set:
|
---|
| 711 | (flStyle & CBS_DROPDOWNLIST)
|
---|
| 712 | ? ES_READONLY
|
---|
| 713 | : 0,
|
---|
| 714 | // mask:
|
---|
| 715 | ES_READONLY); */
|
---|
| 716 | }
|
---|
| 717 | }
|
---|
| 718 |
|
---|
[167] | 719 | return brc;
|
---|
[128] | 720 | }
|
---|
| 721 |
|
---|
| 722 |
|
---|