527 lines
13 KiB
C++
527 lines
13 KiB
C++
|
#include "precomp.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
extern "C"
|
||
|
{
|
||
|
#include <stdexts.h>
|
||
|
};
|
||
|
|
||
|
#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
|
||
|
#define MIN_WIDTH 96
|
||
|
#define MIN_HEIGHT 64
|
||
|
#define BORDER_WIDTH 32
|
||
|
|
||
|
typedef struct _DRAW_ICON_STRUCT
|
||
|
{
|
||
|
HBITMAP hBitmap;
|
||
|
BYTE* psBits;
|
||
|
BITMAPINFO bmi;
|
||
|
HICON hIcon;
|
||
|
int zoom;
|
||
|
} DRAW_ICON_STRUCT;
|
||
|
|
||
|
/************************************************************************\
|
||
|
* Procedure: CreateDIBSectionFromIcon
|
||
|
*
|
||
|
* Description:
|
||
|
*
|
||
|
* Creates a DIB section given the handle to an icon
|
||
|
*
|
||
|
* 3/28/2001 - Created bretan
|
||
|
*
|
||
|
\************************************************************************/
|
||
|
BOOL CreateDIBSectionFromIcon(DRAW_ICON_STRUCT* pDIS)
|
||
|
{
|
||
|
ICONINFO info;
|
||
|
|
||
|
if (!pDIS->hIcon)
|
||
|
{
|
||
|
Print("Invalid HICON handle\n");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (GetIconInfo (pDIS->hIcon, &info))
|
||
|
{
|
||
|
HDC hdc = NULL;
|
||
|
HDC dc = NULL;
|
||
|
HBRUSH hBrush = NULL;
|
||
|
BITMAP bitmap;
|
||
|
|
||
|
hdc = CreateDC(L"DISPLAY", NULL, NULL, NULL);
|
||
|
if (!hdc)
|
||
|
{
|
||
|
Print("CreateDC failed\n");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
dc = CreateCompatibleDC(hdc);
|
||
|
if (!dc)
|
||
|
{
|
||
|
Print("CreateCompatiblDC failed\n");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (!GetObject (info.hbmColor, sizeof (BITMAP), &bitmap))
|
||
|
{
|
||
|
Print("GetObject failed\n");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
pDIS->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||
|
pDIS->bmi.bmiHeader.biWidth = bitmap.bmWidth;
|
||
|
pDIS->bmi.bmiHeader.biHeight = bitmap.bmHeight;
|
||
|
pDIS->bmi.bmiHeader.biPlanes = 1;
|
||
|
pDIS->bmi.bmiHeader.biBitCount = bitmap.bmPlanes * bitmap.bmBitsPixel;
|
||
|
|
||
|
if (pDIS->bmi.bmiHeader.biBitCount <= 1)
|
||
|
{
|
||
|
pDIS->bmi.bmiHeader.biBitCount = 1;
|
||
|
}
|
||
|
else if (pDIS->bmi.bmiHeader.biBitCount <= 4)
|
||
|
{
|
||
|
pDIS->bmi.bmiHeader.biBitCount = 4;
|
||
|
}
|
||
|
else if (pDIS->bmi.bmiHeader.biBitCount <= 8)
|
||
|
{
|
||
|
pDIS->bmi.bmiHeader.biBitCount = 8;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pDIS->bmi.bmiHeader.biBitCount = 24;
|
||
|
}
|
||
|
|
||
|
pDIS->bmi.bmiHeader.biCompression = BI_RGB;
|
||
|
|
||
|
// Create a DIB section so we don't have to worry about the display settings
|
||
|
pDIS->hBitmap = CreateDIBSection(dc, (const BITMAPINFO *)&pDIS->bmi, DIB_RGB_COLORS, (void**)&pDIS->psBits, NULL, 0);
|
||
|
if (pDIS->hBitmap == NULL)
|
||
|
{
|
||
|
Print("CreateDIBSection failed\n");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
SelectObject (dc, pDIS->hBitmap);
|
||
|
hBrush = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
||
|
DrawIconEx (dc, 0, 0, pDIS->hIcon, 0, 0, 0, hBrush, DI_NORMAL);
|
||
|
|
||
|
if (NULL == pDIS->psBits)
|
||
|
{
|
||
|
Print("CreateDIBSection failed.\n");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
DeleteObject (info.hbmMask);
|
||
|
DeleteObject (info.hbmColor);
|
||
|
DeleteDC (hdc);
|
||
|
DeleteDC (dc);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/************************************************************************\
|
||
|
* Procedure: ZoomIn
|
||
|
*
|
||
|
* Description:
|
||
|
*
|
||
|
* Zooms the window in by a factor of 2
|
||
|
*
|
||
|
* 3/28/2001 - Created bretan
|
||
|
*
|
||
|
\************************************************************************/
|
||
|
void ZoomIn(HWND hwnd)
|
||
|
{
|
||
|
DRAW_ICON_STRUCT* pDIS = (DRAW_ICON_STRUCT*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||
|
int w, h;
|
||
|
|
||
|
pDIS->zoom++;
|
||
|
|
||
|
w = pDIS->bmi.bmiHeader.biWidth * pDIS->zoom + BORDER_WIDTH;
|
||
|
h = pDIS->bmi.bmiHeader.biHeight * pDIS->zoom + BORDER_WIDTH;
|
||
|
|
||
|
if (w < MIN_WIDTH) w = MIN_WIDTH;
|
||
|
if (h < MIN_HEIGHT) h = MIN_HEIGHT;
|
||
|
|
||
|
SetWindowPos(hwnd, 0, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE);
|
||
|
InvalidateRect(hwnd, NULL, TRUE);
|
||
|
}
|
||
|
|
||
|
/************************************************************************\
|
||
|
* Procedure: ZoomOut
|
||
|
*
|
||
|
* Description:
|
||
|
*
|
||
|
* Zooms the window out by a factor of 2
|
||
|
*
|
||
|
* 3/28/2001 - Created bretan
|
||
|
*
|
||
|
\************************************************************************/
|
||
|
void ZoomOut(HWND hwnd)
|
||
|
{
|
||
|
DRAW_ICON_STRUCT* pDIS = (DRAW_ICON_STRUCT*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||
|
|
||
|
pDIS->zoom--;
|
||
|
|
||
|
if (pDIS->zoom < 1)
|
||
|
{
|
||
|
pDIS->zoom = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int w = pDIS->bmi.bmiHeader.biWidth * pDIS->zoom + BORDER_WIDTH;
|
||
|
int h = pDIS->bmi.bmiHeader.biHeight * pDIS->zoom + BORDER_WIDTH;
|
||
|
|
||
|
if (w < MIN_WIDTH) w = MIN_WIDTH;
|
||
|
if (h < MIN_HEIGHT) h = MIN_HEIGHT;
|
||
|
|
||
|
SetWindowPos(hwnd, 0, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE);
|
||
|
InvalidateRect(hwnd, NULL, TRUE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/************************************************************************\
|
||
|
* Procedure: WndProc
|
||
|
*
|
||
|
* Description:
|
||
|
*
|
||
|
* The wndproc for the icon window
|
||
|
*
|
||
|
* 3/28/2001 - Created bretan
|
||
|
*
|
||
|
\************************************************************************/
|
||
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
switch (msg)
|
||
|
{
|
||
|
case WM_NCHITTEST: return HTCAPTION;
|
||
|
|
||
|
case WM_PAINT:
|
||
|
{
|
||
|
PAINTSTRUCT ps;
|
||
|
HDC hdc = BeginPaint(hwnd, &ps);
|
||
|
HDC buf = CreateCompatibleDC(hdc);
|
||
|
HBITMAP oldbuf;
|
||
|
RECT r;
|
||
|
DRAW_ICON_STRUCT* pDIS = (DRAW_ICON_STRUCT*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||
|
|
||
|
GetClientRect(hwnd, &r);
|
||
|
FillRect(hdc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
||
|
|
||
|
if (pDIS)
|
||
|
{
|
||
|
int x, y, w, h;
|
||
|
|
||
|
w = pDIS->bmi.bmiHeader.biWidth * pDIS->zoom;
|
||
|
h = pDIS->bmi.bmiHeader.biHeight * pDIS->zoom;
|
||
|
|
||
|
x = r.right/2 - w/2;
|
||
|
y = r.bottom/2 - h/2;
|
||
|
|
||
|
oldbuf = (HBITMAP)SelectObject(buf, pDIS->hBitmap);
|
||
|
StretchBlt(hdc, x, y, w, h, buf, 0, 0, w/pDIS->zoom, h/pDIS->zoom, SRCCOPY);
|
||
|
}
|
||
|
|
||
|
SelectObject(buf, oldbuf);
|
||
|
DeleteDC(buf);
|
||
|
EndPaint(hwnd, &ps);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_NCLBUTTONDBLCLK:
|
||
|
{
|
||
|
ZoomIn(hwnd);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_NCRBUTTONDBLCLK:
|
||
|
{
|
||
|
ZoomOut(hwnd);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_KEYDOWN:
|
||
|
{
|
||
|
switch (wParam)
|
||
|
{
|
||
|
case 187: // '+'
|
||
|
{
|
||
|
ZoomIn(hwnd);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 189: // '-'
|
||
|
{
|
||
|
ZoomOut(hwnd);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 81: // 'q'
|
||
|
{
|
||
|
PostQuitMessage(0);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
/*default:
|
||
|
{
|
||
|
TCHAR szTemp[256];
|
||
|
wsprintf(szTemp, L"%d", wParam);
|
||
|
MessageBox(hwnd, szTemp, szTemp, MB_OK);
|
||
|
}
|
||
|
break;*/
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_SYSCOMMAND:
|
||
|
{
|
||
|
switch (wParam)
|
||
|
{
|
||
|
case SC_CLOSE:
|
||
|
{
|
||
|
PostQuitMessage(0);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_TIMER:
|
||
|
{
|
||
|
if (IsCtrlCHit())
|
||
|
{
|
||
|
PostQuitMessage(0);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
/************************************************************************\
|
||
|
* Procedure: DrawIconWindow
|
||
|
*
|
||
|
* Description:
|
||
|
*
|
||
|
* Draws the icon in a window on the remote side
|
||
|
*
|
||
|
* 3/28/2001 - Created bretan
|
||
|
*
|
||
|
\************************************************************************/
|
||
|
DWORD WINAPI DrawIconWindow(LPVOID inpDIS)
|
||
|
{
|
||
|
MSG msg;
|
||
|
WNDCLASS wc;
|
||
|
HWND hwnd;
|
||
|
DRAW_ICON_STRUCT* pDIS = (DRAW_ICON_STRUCT*)inpDIS;
|
||
|
LPCTSTR szClassName = L"ntsd - drawicon";
|
||
|
TCHAR szTitle[32] = {0};
|
||
|
int w, h;
|
||
|
|
||
|
memset(&wc,0,sizeof(wc));
|
||
|
wc.lpfnWndProc = WndProc;
|
||
|
wc.hInstance = NULL;
|
||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||
|
wc.style = CS_DBLCLKS;
|
||
|
wc.lpszClassName = szClassName;
|
||
|
RegisterClass(&wc);
|
||
|
|
||
|
w = pDIS->bmi.bmiHeader.biWidth + BORDER_WIDTH;
|
||
|
h = pDIS->bmi.bmiHeader.biHeight + BORDER_WIDTH;
|
||
|
|
||
|
if (w < MIN_WIDTH) w = MIN_WIDTH;
|
||
|
if (h < MIN_HEIGHT) h = MIN_HEIGHT;
|
||
|
|
||
|
wsprintf(szTitle, L"%08x", pDIS->hIcon);
|
||
|
hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,
|
||
|
szClassName, szTitle,
|
||
|
WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE,
|
||
|
10, 10,
|
||
|
w, h,
|
||
|
NULL, NULL, NULL, NULL);
|
||
|
if (!hwnd) return FALSE;
|
||
|
|
||
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pDIS);
|
||
|
SetTimer(hwnd, 0, 100, NULL);
|
||
|
SetForegroundWindow(hwnd);
|
||
|
SetFocus(hwnd);
|
||
|
|
||
|
while (GetMessage(&msg, (HWND) NULL, 0, 0))
|
||
|
{
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
|
||
|
KillTimer(hwnd, 0);
|
||
|
DestroyWindow(hwnd);
|
||
|
UnregisterClass(szClassName, NULL);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/************************************************************************\
|
||
|
* Procedure: DrawIconASCII
|
||
|
*
|
||
|
* Description:
|
||
|
*
|
||
|
* Prints the icon in ASCII format through the ntsd session
|
||
|
*
|
||
|
* 3/28/2001 - Created bretan
|
||
|
*
|
||
|
\************************************************************************/
|
||
|
BOOL DrawIconASCII(DRAW_ICON_STRUCT* pDIS, BOOL bColor)
|
||
|
{
|
||
|
HANDLE hConsole;
|
||
|
DWORD dwWritten;
|
||
|
WORD wOldColorAttrs;
|
||
|
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
|
||
|
|
||
|
|
||
|
if (bColor)
|
||
|
{
|
||
|
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||
|
|
||
|
if (hConsole)
|
||
|
{
|
||
|
if (!GetConsoleScreenBufferInfo(hConsole, &csbiInfo))
|
||
|
{
|
||
|
bColor = FALSE;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bColor = FALSE;
|
||
|
}
|
||
|
|
||
|
wOldColorAttrs = csbiInfo.wAttributes;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
// Uncomment this to get a nice big list of all the chars to choose from
|
||
|
for (int x = 0; x < 256; x++)
|
||
|
{
|
||
|
TCHAR szPrint[10];
|
||
|
wsprintf(szPrint, L"%d = %c\n", x, x);
|
||
|
WriteConsole(hConsole, szPrint, lstrlen(szPrint), &dwWritten, NULL);
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
for (int y = pDIS->bmi.bmiHeader.biHeight*3 - 3; y; y-=3)
|
||
|
{
|
||
|
int Offset = y * pDIS->bmi.bmiHeader.biWidth;
|
||
|
|
||
|
for (int x = 0; x < pDIS->bmi.bmiHeader.biWidth*3; x+=3)
|
||
|
{
|
||
|
RGBQUAD* prgb = (RGBQUAD*)&pDIS->psBits[x + Offset];
|
||
|
|
||
|
if (bColor)
|
||
|
{
|
||
|
TCHAR szPrint[3];
|
||
|
WORD wForeground = 0;
|
||
|
|
||
|
if (prgb->rgbRed > 128)
|
||
|
{
|
||
|
wForeground |= FOREGROUND_RED;
|
||
|
}
|
||
|
|
||
|
if (prgb->rgbGreen > 128)
|
||
|
{
|
||
|
wForeground |= FOREGROUND_GREEN;
|
||
|
}
|
||
|
|
||
|
if (prgb->rgbBlue > 128)
|
||
|
{
|
||
|
wForeground |= FOREGROUND_BLUE;
|
||
|
}
|
||
|
|
||
|
if (prgb->rgbRed > 192 || prgb->rgbGreen > 192 || prgb->rgbBlue > 192)
|
||
|
{
|
||
|
wForeground |= FOREGROUND_INTENSITY;
|
||
|
}
|
||
|
|
||
|
SetConsoleTextAttribute(hConsole, wForeground);
|
||
|
wsprintf(szPrint, L"%c%c", 15, 15);
|
||
|
WriteConsole(hConsole, szPrint, 2, &dwWritten, NULL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int val = (prgb->rgbRed + prgb->rgbGreen + prgb->rgbBlue) / 3;
|
||
|
|
||
|
if (val > 0 && val <= 25) Print(" ");
|
||
|
else if (val > 25 && val <= 100) Print("%c%c", 176, 176);
|
||
|
else if (val > 100 && val <= 165) Print("%c%c", 177, 177);
|
||
|
else if (val > 165 && val <= 215) Print("%c%c", 178, 178);
|
||
|
else if (val > 215 && val <= 255) Print("%c%c", 219, 219);
|
||
|
else Print(" ");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bColor)
|
||
|
{
|
||
|
WriteConsole(hConsole, L"\n", 1, &dwWritten, NULL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Print("\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bColor)
|
||
|
{
|
||
|
WriteConsole(hConsole, L"\n", 1, &dwWritten, NULL);
|
||
|
SetConsoleTextAttribute(hConsole, wOldColorAttrs);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Print("\n");
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/************************************************************************\
|
||
|
* Procedure: Idrawicon
|
||
|
*
|
||
|
* Description:
|
||
|
*
|
||
|
* Draws the given icon in ASCII or in a popup window
|
||
|
*
|
||
|
* 3/28/2001 - Created bretan
|
||
|
*
|
||
|
\************************************************************************/
|
||
|
extern "C" BOOL Idrawicon(DWORD dwOpts,
|
||
|
LPVOID pArg )
|
||
|
{
|
||
|
DRAW_ICON_STRUCT DIS;
|
||
|
BOOL ret=FALSE;
|
||
|
HICON hIcon = (HICON)pArg;
|
||
|
|
||
|
DIS.zoom = 1;
|
||
|
DIS.hIcon = hIcon;
|
||
|
|
||
|
ret = CreateDIBSectionFromIcon(&DIS);
|
||
|
|
||
|
if (ret)
|
||
|
{
|
||
|
if (OFLAG(w) & dwOpts)
|
||
|
{
|
||
|
ret = DrawIconWindow(&DIS);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ret = DrawIconASCII(&DIS, (OFLAG(c) & dwOpts)? TRUE : FALSE);
|
||
|
}
|
||
|
|
||
|
DeleteObject(DIS.hBitmap);
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|