summaryrefslogtreecommitdiffstats
path: root/private/nw/convert/nwconv/hierdraw.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/nw/convert/nwconv/hierdraw.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/nw/convert/nwconv/hierdraw.c')
-rw-r--r--private/nw/convert/nwconv/hierdraw.c403
1 files changed, 403 insertions, 0 deletions
diff --git a/private/nw/convert/nwconv/hierdraw.c b/private/nw/convert/nwconv/hierdraw.c
new file mode 100644
index 000000000..7fe150924
--- /dev/null
+++ b/private/nw/convert/nwconv/hierdraw.c
@@ -0,0 +1,403 @@
+#include <windows.h>
+#include <windowsx.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "hierdraw.h"
+
+
+VOID HierDraw_DrawTerm(LPHEIRDRAWSTRUCT lpHierDrawStruct) {
+ if (lpHierDrawStruct->hbmIcons) {
+ if (lpHierDrawStruct->hbmMem)
+ SelectObject(lpHierDrawStruct->hdcMem,lpHierDrawStruct->hbmMem);
+ lpHierDrawStruct->hbmMem = NULL;
+ DeleteObject(lpHierDrawStruct->hbmIcons);
+ lpHierDrawStruct->hbmIcons = NULL;
+ }
+
+ if ( lpHierDrawStruct->hdcMem ) {
+ DeleteDC(lpHierDrawStruct->hdcMem);
+ lpHierDrawStruct->hdcMem = NULL;
+ }
+} // HierDraw_DrawTerm
+
+VOID HierDraw_DrawCloseAll(LPHEIRDRAWSTRUCT lpHierDrawStruct ) {
+ lpHierDrawStruct->NumOpened= 0;
+ if ( lpHierDrawStruct->Opened ) {
+ _ffree(lpHierDrawStruct->Opened);
+ }
+ lpHierDrawStruct->Opened = NULL;
+} // HierDraw_DrawCloseAll
+
+VOID HierDraw_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT FAR* lpMeasureItem,
+ LPHEIRDRAWSTRUCT lpHierDrawStruct) {
+ lpMeasureItem->itemHeight = max(lpHierDrawStruct->nBitmapHeight,
+ lpHierDrawStruct->nTextHeight);
+} // HierDraw_OnMeasureItem
+
+VOID HierDraw_DrawSetTextHeight (HWND hwndList, HFONT hFont, LPHEIRDRAWSTRUCT lpHierDrawStruct ) {
+ TEXTMETRIC TextMetrics;
+ HANDLE hOldFont=NULL;
+ HDC hdc;
+
+ //
+ // This sure looks like a lot of work to find the character height
+ //
+ hdc = GetDC(hwndList);
+
+ hOldFont = SelectObject(hdc, hFont);
+ GetTextMetrics(hdc, &TextMetrics);
+ SelectObject(hdc, hOldFont);
+ ReleaseDC(hwndList, hdc);
+
+ lpHierDrawStruct->nTextHeight = TextMetrics.tmHeight;
+
+ lpHierDrawStruct->nLineHeight =
+ max(lpHierDrawStruct->nBitmapHeight, lpHierDrawStruct->nTextHeight);
+
+ if ( hwndList != NULL )
+ SendMessage(hwndList, LB_SETITEMHEIGHT, 0,
+ MAKELPARAM(lpHierDrawStruct->nLineHeight, 0));
+} // HierDraw_DrawSetTextHeight
+
+static DWORD near RGB2BGR(DWORD rgb) {
+ return RGB(GetBValue(rgb),GetGValue(rgb),GetRValue(rgb));
+} // RGB2BGR
+
+/*
+ * Creates the objects used while drawing the tree. This may be called
+ * repeatedly in the event of a WM_SYSCOLORCHANGED message.
+ *
+ * WARNING: the Tree icons bitmap is assumed to be a 16 color DIB!
+ */
+
+BOOL HierDraw_DrawInit(HINSTANCE hInstance,
+ int nBitmap,
+ int nRows,
+ int nColumns,
+ BOOL bLines,
+ LPHEIRDRAWSTRUCT lpHierDrawStruct,
+ BOOL bInit) {
+ HANDLE hRes;
+ HANDLE hResMem;
+ LPBITMAPINFOHEADER lpbiReadOnly;
+ LPBITMAPINFOHEADER lpbiReadWrite;
+ DWORD *lpColorTable;
+ LPSTR lpBits;
+ int biSize;
+ int bc;
+ HDC hDC;
+
+ if ( bInit ) {
+ lpHierDrawStruct->NumOpened = 0;
+ lpHierDrawStruct->Opened = NULL;
+ lpHierDrawStruct->bLines = bLines;
+ }
+
+ //
+ // If the Memory DC is not created yet do that first.
+ //
+ if (!lpHierDrawStruct->hdcMem) {
+ //
+ // get a screen DC
+ //
+ hDC = GetDC(NULL);
+ //
+ // Create a memory DC compatible with the screen
+ //
+ lpHierDrawStruct->hdcMem = CreateCompatibleDC(hDC);
+ //
+ // Release the Screen DC
+ ReleaseDC(NULL,hDC);
+
+ if (!lpHierDrawStruct->hdcMem)
+ return FALSE;
+
+ lpHierDrawStruct->hbmMem = NULL;
+ }
+
+ //
+ // (Re)Load the Bitmap ( original from disk )
+ //
+ // Use the FindResource,LoadResource,LockResource since it makes
+ // it easy to get the pointer to the BITMAPINFOHEADER we need.
+ //
+ //
+ hRes = FindResource(hInstance, MAKEINTRESOURCE(nBitmap), RT_BITMAP);
+ if (!hRes)
+ return FALSE;
+
+ hResMem = LoadResource(hInstance, hRes);
+ if (!hResMem)
+ return FALSE;
+
+ // Now figure out the bitmaps background color.
+ // This code assumes the lower left corner is a
+ // bit in the background color.
+ lpbiReadOnly = (LPBITMAPINFOHEADER)LockResource(hResMem);
+ if (!lpbiReadOnly)
+ return FALSE;
+
+ // Determine size of bitmap information header plus color table entries
+ biSize = lpbiReadOnly->biSize + ((1 << (lpbiReadOnly->biBitCount)) * sizeof(RGBQUAD));
+
+ // Allocate copy of the bitmap information to munge on
+ lpbiReadWrite = (LPBITMAPINFOHEADER)GlobalAlloc(GPTR, biSize);
+ if (!lpbiReadWrite)
+ return FALSE;
+
+ memcpy(lpbiReadWrite, lpbiReadOnly, biSize);
+
+ // Color table immediately follows bitmap information header
+ lpColorTable = (DWORD FAR *)((LPBYTE)lpbiReadWrite + lpbiReadWrite->biSize);
+
+ // No need to munge bits so use original
+ lpBits = (LPBYTE)lpbiReadOnly + biSize;
+
+ bc = (lpBits[0] & 0xF0) >> 4; // ASSUMES LOWER LEFT CORNER IS BG!!
+
+ lpColorTable[bc] = RGB2BGR(GetSysColor(COLOR_WINDOW));
+
+ hDC = GetDC(NULL);
+
+ lpHierDrawStruct->hbmIcons = CreateDIBitmap(
+ hDC,
+ lpbiReadWrite,
+ CBM_INIT,
+ lpBits,
+ (LPBITMAPINFO)lpbiReadWrite,
+ DIB_RGB_COLORS
+ );
+
+ ReleaseDC(NULL,hDC);
+
+ lpHierDrawStruct->nBitmapHeight = (WORD)lpbiReadWrite->biHeight / nRows;
+ lpHierDrawStruct->nBitmapWidth = (WORD)lpbiReadWrite->biWidth / nColumns;
+
+ lpHierDrawStruct->nLineHeight =
+ max(lpHierDrawStruct->nBitmapHeight, lpHierDrawStruct->nTextHeight);
+
+ GlobalFree(lpbiReadWrite);
+ UnlockResource(hResMem);
+ FreeResource(hResMem);
+
+ if (!lpHierDrawStruct->hbmIcons)
+ return FALSE;
+
+ lpHierDrawStruct->hbmMem = SelectObject(lpHierDrawStruct->hdcMem,lpHierDrawStruct->hbmIcons);
+ if (!lpHierDrawStruct->hbmMem)
+ return FALSE;
+
+ return TRUE;
+} // HierDraw_DrawInit
+
+
+
+VOID HierDraw_OnDrawItem(HWND hwnd,
+ const DRAWITEMSTRUCT FAR* lpDrawItem,
+ int nLevel,
+ DWORD dwConnectLevel,
+ TCHAR *szText,
+ int nRow,
+ int nColumn,
+ LPHEIRDRAWSTRUCT lpHierDrawStruct) {
+ HDC hDC;
+ WORD wIndent, wTopBitmap, wTopText;
+ RECT rcTemp;
+
+
+ if ( lpDrawItem->itemID == (UINT)-1 )
+ return ;
+
+ hDC = lpDrawItem->hDC;
+ CopyRect(&rcTemp, &lpDrawItem->rcItem);
+
+ wIndent = rcTemp.left + ((int)(nLevel) * lpHierDrawStruct->nBitmapWidth) + XBMPOFFSET;
+ rcTemp.left = wIndent + lpHierDrawStruct->nBitmapWidth;
+ wTopText = rcTemp.top + ((rcTemp.bottom - rcTemp.top) / 2) - (lpHierDrawStruct->nTextHeight / 2);
+ wTopBitmap = rcTemp.top + ((rcTemp.bottom - rcTemp.top) / 2) - (lpHierDrawStruct->nBitmapHeight / 2);
+
+ if (lpDrawItem->itemAction == ODA_FOCUS)
+ goto DealWithFocus;
+ else if (lpDrawItem->itemAction == ODA_SELECT)
+ goto DealWithSelection;
+
+ //
+ // Draw some lions, if we like lions
+ //
+
+ if (lpHierDrawStruct->bLines && nLevel)
+ {
+ DWORD dwMask = 1;
+ int nTempLevel;
+ int x,y;
+
+ // draw lines in text color
+ SetBkColor(hDC,GetSysColor(COLOR_WINDOWTEXT));
+
+ //
+ // Draw a series of | lines for outer levels
+ //
+
+ x = lpHierDrawStruct->nBitmapWidth/2 + XBMPOFFSET;
+
+ for ( nTempLevel = 0; nTempLevel < nLevel ; nTempLevel++)
+ {
+ if ( dwConnectLevel & dwMask )
+ FastRect(hDC,x,rcTemp.top,1,rcTemp.bottom - rcTemp.top);
+
+ x += lpHierDrawStruct->nBitmapWidth;
+ dwMask *= 2;
+ }
+
+
+ //
+ // Draw the short vert line up towards the parent
+ //
+ nTempLevel = nLevel-1;
+ dwMask *= 2;
+
+ x = nTempLevel * lpHierDrawStruct->nBitmapWidth + lpHierDrawStruct->nBitmapWidth / 2 + XBMPOFFSET;
+
+ if ( dwConnectLevel & dwMask )
+ y = rcTemp.bottom;
+ else
+ y = rcTemp.bottom - lpHierDrawStruct->nLineHeight / 2;
+
+ FastRect(hDC,x,rcTemp.top,1,y-rcTemp.top);
+
+ //
+ // Draw short horiz bar to right
+ //
+ FastRect(hDC,x,rcTemp.bottom-lpHierDrawStruct->nLineHeight/2,lpHierDrawStruct->nBitmapWidth/2,1);
+ }
+
+ //
+ // Draw the selected bitmap
+ //
+
+ BitBlt(hDC,
+ wIndent,wTopBitmap,
+ lpHierDrawStruct->nBitmapWidth,lpHierDrawStruct->nBitmapHeight,
+ lpHierDrawStruct->hdcMem,
+ nColumn*lpHierDrawStruct->nBitmapWidth,
+ nRow*lpHierDrawStruct->nBitmapHeight,
+ SRCCOPY);
+
+DealWithSelection:
+
+ if (lpDrawItem->itemState & ODS_SELECTED)
+ {
+ SetBkColor(hDC,GetSysColor(COLOR_HIGHLIGHT));
+ SetTextColor(hDC,GetSysColor(COLOR_HIGHLIGHTTEXT));
+ }
+ else
+ {
+ SetBkColor(hDC,GetSysColor(COLOR_WINDOW));
+ SetTextColor(hDC,GetSysColor(COLOR_WINDOWTEXT));
+ }
+
+
+ ExtTextOut(hDC, rcTemp.left + 1, wTopText, ETO_CLIPPED|ETO_OPAQUE,
+ &rcTemp,szText,lstrlen(szText), NULL);
+
+ if (lpDrawItem->itemState & ODS_FOCUS && lpDrawItem->itemAction != ODA_SELECT) {
+DealWithFocus:
+ DrawFocusRect(hDC, &rcTemp);
+ }
+
+
+} // HierDraw_OnDrawItem
+
+
+//
+// draw a solid color rectangle quickly
+//
+static VOID near FastRect(HDC hDC, int x, int y, int cx, int cy) {
+ RECT rc;
+
+ rc.left = x;
+ rc.right = x+cx;
+ rc.top = y;
+ rc.bottom = y+cy;
+ ExtTextOut(hDC,x,y,ETO_OPAQUE,&rc,NULL,0,NULL);
+} // FastRect
+
+
+BOOL HierDraw_IsOpened(LPHEIRDRAWSTRUCT lpHierDrawStruct, DWORD dwData) {
+ // For Now just a dumb search
+ //
+ int Count;
+
+ for ( Count = 0; Count < lpHierDrawStruct->NumOpened; Count++ ) {
+ if ( lpHierDrawStruct->Opened[Count] == dwData ) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+
+} // HierDraw_IsOpened
+
+
+VOID HierDraw_OpenItem(LPHEIRDRAWSTRUCT lpHierDrawStruct, DWORD dwData) {
+ lpHierDrawStruct->NumOpened++;
+
+ if (lpHierDrawStruct->Opened == NULL )
+ lpHierDrawStruct->Opened =
+ (DWORD FAR *)_fmalloc(sizeof(DWORD)*lpHierDrawStruct->NumOpened);
+ else
+ lpHierDrawStruct->Opened =
+ (DWORD FAR *)_frealloc(lpHierDrawStruct->Opened,
+ sizeof(DWORD)*lpHierDrawStruct->NumOpened);
+
+ lpHierDrawStruct->Opened[lpHierDrawStruct->NumOpened-1] = dwData;
+} // HierDraw_OpenItem
+
+
+VOID HierDraw_CloseItem(LPHEIRDRAWSTRUCT lpHierDrawStruct, DWORD dwData) {
+ // For Now just a dumb search
+ //
+ int Count;
+
+ for ( Count = 0; Count < lpHierDrawStruct->NumOpened; Count++ ) {
+ if ( lpHierDrawStruct->Opened[Count] == dwData ) {
+ if (--lpHierDrawStruct->NumOpened == 0 ) {
+ _ffree(lpHierDrawStruct->Opened);
+ lpHierDrawStruct->Opened = NULL;
+ }
+ else {
+ if ( Count < lpHierDrawStruct->NumOpened ) {
+ _fmemmove(&(lpHierDrawStruct->Opened[Count]),
+ &(lpHierDrawStruct->Opened[Count+1]),
+ sizeof(DWORD)*(lpHierDrawStruct->NumOpened-Count));
+ }
+ lpHierDrawStruct->Opened =
+ (DWORD FAR *)_frealloc(lpHierDrawStruct->Opened,
+ sizeof(DWORD)*lpHierDrawStruct->NumOpened);
+ }
+ }
+ }
+} // HierDraw_CloseItem
+
+
+VOID HierDraw_ShowKids(LPHEIRDRAWSTRUCT lpHierDrawStruct,
+ HWND hwndList, WORD wCurrentSelection, WORD wKids) {
+ WORD wBottomIndex;
+ WORD wTopIndex;
+ WORD wNewTopIndex;
+ WORD wExpandInView;
+ RECT rc;
+
+ wTopIndex = (WORD)SendMessage(hwndList, LB_GETTOPINDEX, 0, 0L);
+ GetClientRect(hwndList, &rc);
+ wBottomIndex = wTopIndex + (rc.bottom+1) / lpHierDrawStruct->nLineHeight;
+
+ wExpandInView = (wBottomIndex - wCurrentSelection);
+
+ if (wKids >= wExpandInView) {
+ wNewTopIndex = min(wCurrentSelection, wTopIndex + wKids - wExpandInView + 1);
+ SendMessage(hwndList, LB_SETTOPINDEX, (WORD)wNewTopIndex, 0L);
+ }
+
+} // HierDraw_ShowKids