summaryrefslogtreecommitdiffstats
path: root/private/sdktools/ddespy/lists.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/sdktools/ddespy/lists.c')
-rw-r--r--private/sdktools/ddespy/lists.c433
1 files changed, 433 insertions, 0 deletions
diff --git a/private/sdktools/ddespy/lists.c b/private/sdktools/ddespy/lists.c
new file mode 100644
index 000000000..5e780bc41
--- /dev/null
+++ b/private/sdktools/ddespy/lists.c
@@ -0,0 +1,433 @@
+/*
+ * 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);
+
+ }
+}
+
+