home *** CD-ROM | disk | FTP | other *** search
-
- /******************************************************************************\
- * This is a part of the Microsoft Source Code Samples.
- * Copyright (C) 1993-1997 Microsoft Corporation.
- * All rights reserved.
- * This source code is only intended as a supplement to
- * Microsoft Development Tools and/or WinHelp documentation.
- * See these sources for detailed information regarding the
- * Microsoft samples programs.
- \******************************************************************************/
-
- /*
- * LISTS.C
- *
- * This file implements a generalized multi-collumn listbox with a standard
- * frame window.
- */
- #define UNICODE
- #include <windows.h>
- #include <windowsx.h>
- #include <string.h>
- #include <stdlib.h>
- #include "ddespy.h"
- #include "globals.h"
- #include "lists.h"
-
- int CompareItems(LPTSTR psz1, LPTSTR psz2, INT SortCol, INT cCols);
- int CmpCols(LPTSTR psz1, LPTSTR psz2, INT SortCol);
- void DrawLBItem(LPDRAWITEMSTRUCT lpdis);
- long CALLBACK MCLBClientWndProc(HWND hwnd, UINT msg, WPARAM wParam, LONG lPAram);
-
- UINT cyHeading;
-
-
- #ifdef UNICODE
-
- #define atoi atoiW
-
-
- //*********************************************************************
- //
- // atoiW
- //
- // Unicode version of atoi.
- //
-
- INT atoiW (LPTSTR s) {
- INT i = 0;
-
- while (isdigit (*s)) {
- i = i*10 + (BYTE)*s - TEXT('0');
- s++;
- }
- return i;
- }
-
- #endif
-
- HWND CreateMCLBFrame(
- HWND hwndParent,
- LPTSTR lpszTitle, // frame title string
- UINT dwStyle, // frame styles
- HICON hIcon,
- HBRUSH hbrBkgnd, // background for heading.
- LPTSTR lpszHeadings) // tab delimited list of headings. The number of
- // headings indicate the number of collumns.
- {
- static BOOL fRegistered = FALSE;
- MCLBCREATESTRUCT mclbcs;
-
- if (!fRegistered) {
- WNDCLASS wc;
- HDC hdc;
- TEXTMETRIC tm;
-
- wc.style = WS_OVERLAPPED | CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = MCLBClientWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 4;
- wc.hInstance = hInst;
- wc.hIcon = hIcon;
- wc.hCursor = NULL;
- wc.hbrBackground = hbrBkgnd;
- wc.lpszMenuName = NULL;
- wc.lpszClassName = (LPCTSTR) RefString(IDS_LISTCLASS);
- RegisterClass(&wc);
-
- hdc = GetDC(GetDesktopWindow());
- GetTextMetrics(hdc, &tm);
- cyHeading = tm.tmHeight;
- ReleaseDC(GetDesktopWindow(), hdc);
-
- fRegistered = TRUE;
- }
- mclbcs.lpszHeadings = lpszHeadings;
-
- return(CreateWindow((LPCTSTR) RefString(IDS_LISTCLASS),
- (LPCTSTR) lpszTitle, dwStyle,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- hwndParent, NULL, hInst, (LPVOID)&mclbcs));
- }
-
-
- LONG CALLBACK MCLBClientWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- MCLBSTRUCT *pmclb;
- RECT rc;
- INT i;
-
- if (msg == WM_CREATE) {
- LPTSTR psz;
- MCLBCREATESTRUCT FAR *pcs;
-
- pcs = (MCLBCREATESTRUCT FAR *)((LPCREATESTRUCT)lParam)->lpCreateParams;
- pmclb = (MCLBSTRUCT *)LocalAlloc(LPTR, sizeof(MCLBSTRUCT));
- psz = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)
- * (lstrlen(pcs->lpszHeadings) + 1));
- lstrcpy((LPTSTR)psz, pcs->lpszHeadings);
- pmclb->pszHeadings = psz;
- pmclb->cCols = 1;
- while (*psz) {
- if (*psz == '\t') {
- pmclb->cCols++;
- }
- psz++;
- }
- pmclb->SortCol = 0;
- SetWindowLong(hwnd, 0, (UINT)pmclb);
- GetClientRect(hwnd, &rc);
- pmclb->hwndLB = CreateWindow((LPCTSTR) RefString(IDS_LBOX),
- (LPCTSTR) szNULL,
- MYLBSTYLE | WS_VISIBLE,
- 0, 0, 0, 0, hwnd, (HMENU)pmclb->cCols, hInst, NULL);
- return(pmclb->hwndLB ? 0 : -1);
- }
-
- pmclb = (MCLBSTRUCT *)GetWindowLong(hwnd, 0);
-
- switch (msg) {
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- DRAWITEMSTRUCT dis;
-
- BeginPaint(hwnd, &ps);
- SetBkMode(ps.hdc, TRANSPARENT);
- dis.hwndItem = hwnd;
- dis.hDC = ps.hdc;
- GetClientRect(hwnd, &dis.rcItem);
- dis.rcItem.bottom = dis.rcItem.top + cyHeading;
- dis.CtlType = ODT_BUTTON; // hack to avoid erasure
- dis.CtlID = pmclb->cCols;
- dis.itemID = 0;
- dis.itemAction = ODA_DRAWENTIRE;
- dis.itemData = (UINT)(LPTSTR)pmclb->pszHeadings;
- dis.itemState = 0;
- DrawLBItem(&dis);
- EndPaint(hwnd, &ps);
- }
- break;
-
- case WM_SIZE:
- MoveWindow(pmclb->hwndLB, 0, cyHeading, LOWORD(lParam),
- HIWORD(lParam) - cyHeading, TRUE);
- break;
-
- case WM_LBUTTONDOWN:
- {
- HWND hwndLB;
- INT i;
-
- // determine which collumn the mouse landed and sort on that collumn.
-
- SendMessage(hwnd, WM_SETREDRAW, 0, 0);
- GetClientRect(hwnd, &rc);
- InflateRect(&rc, -1, -1);
- pmclb->SortCol = LOWORD(lParam) * pmclb->cCols / (rc.right - rc.left);
- hwndLB = CreateWindow((LPCTSTR) RefString(IDS_LBOX),
- (LPCTSTR) szNULL, MYLBSTYLE, 1, cyHeading + 1,
- rc.right - rc.left, rc.bottom - rc.top - cyHeading,
- hwnd, (HMENU)pmclb->cCols, hInst, NULL);
- for (i = (INT)SendMessage(pmclb->hwndLB, LB_GETCOUNT, 0, 0); i;
- i--) {
- SendMessage(hwndLB, LB_ADDSTRING, 0,
- SendMessage(pmclb->hwndLB, LB_GETITEMDATA, i - 1, 0));
- SendMessage(pmclb->hwndLB, LB_SETITEMDATA, i - 1, 0);
- }
- ShowWindow(hwndLB, SW_SHOW);
- ShowWindow(pmclb->hwndLB, SW_HIDE);
- DestroyWindow(pmclb->hwndLB);
- pmclb->hwndLB = hwndLB;
- SendMessage(hwnd, WM_SETREDRAW, 1, 0);
- InvalidateRect(hwnd, NULL, FALSE);
- }
- break;
-
- case WM_DELETEITEM:
-
- if ((UINT)((LPDELETEITEMSTRUCT)lParam)->itemData)
- LocalFree(LocalHandle((PVOID)((LPDELETEITEMSTRUCT)lParam)->itemData));
- break;
-
- case WM_MEASUREITEM:
- ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = cyHeading;
- break;
-
- case WM_DRAWITEM:
- GetClientRect(hwnd, &rc);
- // This fudge makes the collumns line up with the heading.
- ((LPDRAWITEMSTRUCT)lParam)->rcItem.right = rc.right;
- DrawLBItem((LPDRAWITEMSTRUCT)lParam);
- return(DefWindowProc(hwnd, msg, wParam, lParam));
- break;
-
- case WM_COMPAREITEM:
- return(CompareItems((LPTSTR)((LPCOMPAREITEMSTRUCT)lParam)->itemData1,
- (LPTSTR)((LPCOMPAREITEMSTRUCT)lParam)->itemData2,
- pmclb->SortCol,
- pmclb->cCols));
- break;
-
- case WM_DESTROY:
- LocalFree(LocalHandle((PVOID)pmclb->pszHeadings));
- LocalFree(LocalHandle((PVOID)pmclb));
- break;
-
- case WM_CLOSE:
- for (i = 0; i < IT_COUNT && (hwndTrack[i] != hwnd); i++) {
- ;
- }
- pro.fTrack[i] = FALSE;
- hwndTrack[i] = NULL;
- SetFilters();
- DestroyWindow(hwnd);
- break;
-
- default:
- return(DefWindowProc(hwnd, msg, wParam, lParam));
- }
- }
-
-
-
-
- /*
- * Make this return FALSE if addition not needed.
- *
- * if pszSearch != NULL, searches for pszSearch - collumns may contain
- * wild strings - TEXT("*")
- * If found, the string is removed from the LB.
- * Adds pszReplace to LB.
- */
- VOID AddMCLBText(LPTSTR pszSearch, LPTSTR pszReplace, HWND hwndLBFrame)
- {
- MCLBSTRUCT *pmclb;
- INT lit;
- LPTSTR psz;
-
- pmclb = (MCLBSTRUCT *)GetWindowLong(hwndLBFrame, 0);
-
- SendMessage(pmclb->hwndLB, WM_SETREDRAW, 0, 0);
- if (pszSearch != NULL) {
- lit = (INT)SendMessage(pmclb->hwndLB, LB_FINDSTRING, (WPARAM)-1, (LONG)(LPTSTR)pszSearch);
- if (lit >= 0) {
- SendMessage(pmclb->hwndLB, LB_DELETESTRING, lit, 0);
- }
- }
- psz = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * (lstrlen(pszReplace) + 1));
- lstrcpy(psz, pszReplace);
- SendMessage(pmclb->hwndLB, WM_SETREDRAW, 1, 0);
- SendMessage(pmclb->hwndLB, LB_ADDSTRING, 0, (LONG)(LPTSTR)psz);
- }
-
-
- /*
- * This function assumes that the text in cCol is an ASCII number. 0 is
- * returned if it is not found.
- */
- INT GetMCLBColValue(LPTSTR pszSearch, HWND hwndLBFrame, INT cCol)
- {
- MCLBSTRUCT *pmclb;
- LPTSTR psz;
- INT lit;
-
- pmclb = (MCLBSTRUCT *)GetWindowLong(hwndLBFrame, 0);
-
- lit = (INT)SendMessage(pmclb->hwndLB, LB_FINDSTRING, (WPARAM)-1,
- (LPARAM)(LPTSTR)pszSearch);
- if (lit < 0) {
- return(0);
- }
- psz = (LPTSTR)SendMessage(pmclb->hwndLB, LB_GETITEMDATA, lit, 0);
- while (--cCol && (psz = wcschr(psz, '\t') + 1)) {
- ;
- }
- if (psz) {
- return(atoi(psz));
- } else {
- return(0);
- }
- }
-
-
-
- /*
- * Returns fFoundAndRemoved
- */
- BOOL DeleteMCLBText(LPTSTR pszSearch, HWND hwndLBFrame)
- {
- MCLBSTRUCT *pmclb;
- INT lit;
-
- pmclb = (MCLBSTRUCT *)GetWindowLong(hwndLBFrame, 0);
- lit = (INT)SendMessage(pmclb->hwndLB, LB_FINDSTRING, (WPARAM)-1,
- (LONG)(LPTSTR)pszSearch);
- if (lit >= 0) {
- SendMessage(pmclb->hwndLB, LB_DELETESTRING, lit, 0);
- return(TRUE);
- }
- return(FALSE);
- }
-
-
- /*
- * Returns >0 if item1 comes first, <0 if item2 comes first, 0 if ==.
- */
- INT CompareItems(LPTSTR psz1, LPTSTR psz2, INT SortCol, INT cCols)
- {
- INT i, Col;
-
- i = CmpCols(psz1, psz2, SortCol);
- if (i != 0) {
- return(i);
- }
- for (Col = 0; Col < cCols; Col++) {
- if (Col == SortCol) {
- continue;
- }
- i = CmpCols(psz1, psz2, Col);
- if (i != 0) {
- return(i);
- }
- }
- return(0);
- }
-
-
- INT CmpCols(LPTSTR psz1, LPTSTR psz2, INT SortCol)
- {
- LPTSTR psz, pszT1, pszT2;
- INT iRet;
-
- while (SortCol--) {
- psz = wcschr(psz1, '\t');
- if (psz != NULL) {
- psz1 = psz + 1;
- } else {
- psz1 = psz1 + lstrlen(psz1);
- }
- psz = wcschr(psz2, '\t');
- if (psz != NULL) {
- psz2 = psz + 1;
- } else {
- psz2 = psz2 + lstrlen(psz2);
- }
- }
- pszT1 = wcschr(psz1, '\t');
- pszT2 = wcschr(psz2, '\t');
-
- if (pszT1) {
- *pszT1 = '\0';
- }
- if (pszT2) {
- *pszT2 = '\0';
- }
-
- if (!lstrcmp((LPCTSTR)RefString(IDS_WILD), psz1)
- || !lstrcmp((LPCTSTR) RefString(IDS_WILD), psz2)) {
- iRet = 0;
- } else {
- iRet = lstrcmp(psz1, psz2);
- }
-
- if (pszT1) {
- *pszT1 = '\t';
- }
- if (pszT2) {
- *pszT2 = '\t';
- }
-
- return(iRet);
- }
-
-
-
- VOID DrawLBItem(LPDRAWITEMSTRUCT lpdis)
- {
- RECT rcDraw;
- INT cxSection;
- LPTSTR psz, pszEnd;
-
- if (!lpdis->itemData)
- return;
- if ((lpdis->itemAction & ODA_DRAWENTIRE) ||
- ((lpdis->itemAction & ODA_SELECT) &&
- (lpdis->itemState & ODS_SELECTED))) {
- rcDraw = lpdis->rcItem;
- if (lpdis->CtlType != ODT_BUTTON) { // hack to avoid erasure
- HBRUSH hbr;
-
- hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
- FillRect(lpdis->hDC, &lpdis->rcItem, hbr);
- DeleteObject(hbr);
- }
- cxSection = (rcDraw.right - rcDraw.left) / lpdis->CtlID;
- psz = (LPTSTR)(UINT)lpdis->itemData;
- rcDraw.right = rcDraw.left + cxSection;
- while (pszEnd = wcschr(psz, '\t')) {
- *pszEnd = '\0';
- DrawText(lpdis->hDC, psz, -1, &rcDraw, DT_LEFT);
- OffsetRect(&rcDraw, cxSection, 0);
- *pszEnd = '\t';
- psz = pszEnd + 1;
- }
- DrawText(lpdis->hDC, psz, -1, &rcDraw, DT_LEFT);
-
- if (lpdis->itemState & ODS_SELECTED)
- InvertRect(lpdis->hDC, &lpdis->rcItem);
-
- if (lpdis->itemState & ODS_FOCUS)
- DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
-
- } else if (lpdis->itemAction & ODA_SELECT) {
-
- InvertRect(lpdis->hDC, &lpdis->rcItem);
-
- } else if (lpdis->itemAction & ODA_FOCUS) {
-
- DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
-
- }
- }
-