2020-09-30 17:12:29 +02:00

262 lines
7.6 KiB
C++

#include "stdafx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static int iGrind;
HBITMAP hbmpGrind;
const int BMP_WIDTH = 32;
const int BMP_HEIGHT = 32;
const int C_GRIND_IMAGES = 8 - 1;
HDC hdcMem, hdcWnd;
HBITMAP hbmpPreSelect;
static int lPad;
static int tPad;
static const char txtGrindClassName[] = "GrindClass";
LRESULT STDCALL GrindWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static DWORD STDCALL GetTextDimensions(HWND hwnd, PCSTR psz);
/***************************************************************************
FUNCTION: InitGrind
PURPOSE: Initialize the grinder window
PARAMETERS:
void
RETURNS:
COMMENTS:
MODIFICATION DATES:
11-Oct-1993 [ralphw]
***************************************************************************/
BOOL STDCALL InitGrind(PCSTR pszTitle)
{
static BOOL fRegistered = FALSE;
if (iflags.fNoGrinder)
return TRUE;
hbmpGrind = LoadBitmap(hinstApp, MAKEINTRESOURCE(IDBMP_GRIND));
ASSERT(hbmpGrind);
hdcMem = CreateCompatibleDC(NULL);
if (!hdcMem)
return FALSE;
if (!fRegistered) {
WNDCLASS wc;
memset(&wc, 0, sizeof(wc));
// Register Main window class
wc.hInstance = hinstApp;
wc.style = CS_BYTEALIGNWINDOW | CS_CLASSDC;
wc.lpfnWndProc = GrindWndProc;
wc.lpszClassName = txtGrindClassName;
wc.hIcon = LoadIcon(hinstApp, MAKEINTRESOURCE(IDI_HCRTF));
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
if (!RegisterClass(&wc))
return FALSE;
fRegistered = TRUE;
}
RECT rc;
GetWindowRect(hwndParent ? hwndParent : GetDesktopWindow(), &rc);
PCSTR pszWindowTitle = (pszTitle ?
pszTitle : GetStringResource(IDS_GRINDER_TITLE));
int width = LOWORD(GetTextDimensions(NULL, pszWindowTitle)) +
GetSystemMetrics(SM_CXSIZE) * 2;
hwndGrind = CreateWindowEx(WS_EX_WINDOWEDGE, txtGrindClassName,
pszWindowTitle,
WS_SYSMENU | WS_CAPTION | WS_DLGFRAME,
rc.left + RECT_WIDTH(rc) / 2 - width / 2,
rc.top + RECT_HEIGHT(rc) / 2 - BMP_HEIGHT / 2,
width + GetSystemMetrics(SM_CXDLGFRAME) * 2 + 2,
BMP_HEIGHT + GetSystemMetrics(SM_CYDLGFRAME) * 2 + 6 +
GetSystemMetrics(SM_CYMENU),
hwndParent, NULL,
hinstApp, NULL);
lPad = width / 2 - GetSystemMetrics(SM_CXDLGFRAME) - 1;
tPad = 3;
if (!hwndGrind)
return FALSE;
hbmpPreSelect = (HBITMAP) SelectObject(hdcMem, hbmpGrind);
ASSERT(hbmpPreSelect);
ShowWindow(hwndGrind, SW_NORMAL);
FlushMessageQueue();
if (hwndParent)
SendMessage(hwndParent, WMP_HWND_GRINDER, (WPARAM) hwndGrind, 0);
// This is a class DC, and therefore does not have to be released
hdcWnd = GetDC(hwndGrind);
doGrind();
return TRUE;
}
/*
* This is the minimum milliseconds that must pass before updating the
* grinder. Helps to smooth out the animation.
*/
const int GRIND_INCREMENTS = 250;
void STDCALL doGrind(void)
{
static DWORD oldTickCount = 0;
if (hwndGrind) {
FlushMessageQueue();
DWORD curTickCount = GetTickCount();
if (curTickCount - oldTickCount < GRIND_INCREMENTS) {
return;
}
oldTickCount = curTickCount;
BitBlt(hdcWnd, lPad, tPad, BMP_WIDTH, BMP_HEIGHT, hdcMem,
iGrind * BMP_WIDTH, 0, SRCCOPY);
if (++iGrind > C_GRIND_IMAGES)
iGrind = 0;
}
}
void STDCALL RemoveGrind(void)
{
if (!hbmpGrind)
return; // we were never initialized
if (hbmpPreSelect && hdcMem)
SelectObject(hdcMem, hbmpPreSelect);
if (hdcMem) {
DeleteDC(hdcMem);
hdcMem = NULL;
}
RemoveGdiObject(&hbmpGrind);
if (hwndGrind) {
DestroyWindow(hwndGrind);
hwndGrind = NULL;
FlushMessageQueue();
}
// Tell our parent that they no longer have a valid window handle
if (hwndParent)
SendMessage(hwndParent, WMP_HWND_GRINDER, (WPARAM) (HWND) 0, 0);
}
void STDCALL FlushMessageQueue(void)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT STDCALL GrindWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_KEYUP:
if (wParam != VK_ESCAPE)
return 0;
// deliberately fall through
case WM_CLOSE:
case WMP_STOP_GRINDING:
{
CStr csz(IDS_TITLE);
if (MessageBox(hwnd, GetStringResource(IDS_CONFIRM_ABORT),
csz, MB_YESNO) == IDNO)
return 0;
}
RemoveGrind();
SendStringToParent(GetStringResource(IDS_USER_ABORTING));
if (hwndParent)
PostMessage(hwndParent, WMP_STOP_COMPILING, 0, 0);
//throw EXCEPT_DIE_HORRIBLY;
RaiseException( 0x01010101, EXCEPTION_NONCONTINUABLE, 0, NULL );
return 0;
case WM_DESTROY:
if (hbmpGrind) {
/*
* Set hwndGrind to NULL so that RemoveGrind() won't call
* DestroyWindow().
*/
hwndGrind = NULL;
RemoveGrind();
SendStringToParent(GetStringResource(IDS_USER_ABORTING));
//throw EXCEPT_DIE_HORRIBLY;
RaiseException( 0x01010101, EXCEPTION_NONCONTINUABLE, 0, NULL );
}
return 0;
case WM_TCARD:
fCntJump = (int) wParam;
return 0;
case WMP_NO_ACTIVATE:
fNoActivation = TRUE;
return 0;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
/***************************************************************************
FUNCTION: GetTextDimensions
PURPOSE: Get the width/height of the button
PARAMETERS:
hwnd
psz
RETURNS:
COMMENTS:
MODIFICATION DATES:
04-Feb-1993 [ralphw]
***************************************************************************/
static DWORD STDCALL GetTextDimensions(HWND hwnd, PCSTR psz)
{
HDC hdc = GetDC(hwnd);
if (hdc == NULL)
return 0L;
SIZE size;
GetTextExtentPoint(hdc, psz, strlen(psz), &size);
ReleaseDC(hwnd, hdc);
return MAKELONG(size.cx, size.cy);
}