Example #1
0
LRESULT CALLBACK
ChildWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    HDC		hdcMem;
    HBITMAP		hbmp, hbmpOrg;
    RECT		rc;
    PAINTSTRUCT	ps;

    switch(msg) {
    case WM_PAINT:
        BeginPaint(hwnd, &ps);
        GetClientRect(hwnd, &rc);

        /* redirect painting to offscreen dc*/
        hdcMem = CreateCompatibleDC(ps.hdc);
        hbmp = CreateCompatibleBitmap(hdcMem, image->width, image->height);
        hbmpOrg = SelectObject(hdcMem, hbmp);

        /* draw onto offscreen dc*/
        DrawDIB(hdcMem, 0, 0, image);

        /* stretch blit offscreen with physical screen*/
        StretchBlt(ps.hdc, 0, 0, rc.right, rc.bottom, hdcMem,
                   0, 0, image->width, image->height, MWROP_COPY);
        DeleteObject(SelectObject(hdcMem, hbmpOrg));
        DeleteDC(hdcMem);
        EndPaint(hwnd, &ps);
        break;
    default:
        return DefWindowProc( hwnd, msg, wp, lp);
    }
    return 0;
}
void COXImageViewer::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	if(m_dib.IsEmpty())
		return;
	
	// TODO: Add your message handler code here
	OnPrepareDC(&dc);

	// get the size of image
	CSize sizeDIB=GetDIBSize();
	CRect rect(0,0,sizeDIB.cx,sizeDIB.cy);
	CRect rectPaint=rect;
	// transform coordinates of boundary rectangle
	// taking into account current zoom level
	NormalToScaled(&rectPaint);

	///
	// we have to revert Y-coordinates
	// to get right print output
	UINT diff=rect.bottom-rect.top;
	rect.bottom=sizeDIB.cy-rect.top;
	rect.top=rect.bottom-diff;
	///
	DrawDIB(&dc,rectPaint,rect);

	// Do not call COXScrollWnd::OnPaint() for painting messages
}
Example #3
0
LRESULT CALLBACK
ChildWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
	RECT		rc;
	PAINTSTRUCT	ps;

	switch(msg) {
	case WM_PAINT:
		BeginPaint(hwnd, &ps);
		GetClientRect(hwnd, &rc);
#if USEBLIT
{
		HDC		hdcMem;
		HBITMAP		hbmp, hbmpOrg;

		/* redirect painting to offscreen dc, then use blit function*/
		hdcMem = CreateCompatibleDC(ps.hdc);
		hbmp = CreateCompatibleBitmap(hdcMem, rc.right, rc.bottom);
		hbmpOrg = SelectObject(hdcMem, hbmp);

		/* draw onto offscreen dc*/
		DrawDIB(hdcMem, 0, 0, image);

		/* blit offscreen with physical screen*/
		BitBlt(ps.hdc, 0, 0, rc.right, rc.bottom, hdcMem,
			0, 0, MWROP_SRCCOPY);
		/*StretchBlt(ps.hdc, 0, 0, rc.right, rc.bottom, hdcMem,
			0, 0, image->width/3*5, image->height/3*4, MWROP_SRCCOPY);*/
		DeleteObject(SelectObject(hdcMem, hbmpOrg));
		DeleteDC(hdcMem);
}
#else
		DrawDIB(ps.hdc, rc.left, rc.top, image);
#endif
		EndPaint(hwnd, &ps);
		break;
	default:
		return DefWindowProc( hwnd, msg, wp, lp);
	}
	return( 0);
}
Example #4
0
void CVideoDlg::OnReceiveComplete(void)
{
	m_nCount++;
	switch (m_pContext->m_DeCompressionBuffer.GetBuffer(0)[0])
	{
	case TOKEN_WEBCAM_DIB:
		{
			DrawDIB();                  //这里是绘图函数,转到他的代码看一下
			break;
		}	
	}
}
Example #5
0
void CWebCamDlg::OnReceiveComplete()
{
	m_nCount++;
	switch (m_pContext->m_DeCompressionBuffer.GetBuffer(0)[0])
	{
	case TOKEN_WEBCAM_DIB:
		DrawDIB();
		break;
	default:
		// 传输发生异常数据
		SendException();
		break;
	}
}
Example #6
0
void CDIBitmap :: DrawDIB( CDC* pDC, int x, int y ) {
	DrawDIB( pDC, x, y, GetWidth(), GetHeight() );
}
Example #7
0
HBITMAP KDIB::TransformBitmap(XFORM * xm, COLORREF crBack, int method)
{
	int x0, y0, x1, y1, x2, y2, x3, y3;

	Map(xm, 0,        0,         x0, y0);  // 0    1
	Map(xm, m_nWidth, 0,         x1, y1);  //
	Map(xm, 0,        m_nHeight, x2, y2);  // 2    3
	Map(xm, m_nWidth, m_nHeight, x3, y3);

	int xmin, xmax;
	int ymin, ymax;

	minmax(x0, x1, x2, x3, xmin, xmax);
	minmax(y0, y1, y2, y3, ymin, ymax);

	int destwidth  = xmax - xmin;
	int destheight = ymax - ymin;

	KBitmapInfo dest;
	dest.SetFormat(destwidth, destheight, m_pBMI->bmiHeader.biBitCount, m_pBMI->bmiHeader.biCompression);

	if ( m_nClrUsed )
		memcpy(dest.m_dibinfo.bmiColors, m_pRGBQUAD, sizeof(RGBQUAD) * m_nClrUsed);

	// create destination DIB section
	BYTE * pBits;
	HBITMAP hBitmap = CreateDIBSection(NULL, dest.GetBMI(), DIB_RGB_COLORS, (void **) & pBits, NULL, NULL);
	if ( hBitmap==NULL )
	{
		assert(false);
		return NULL;
	}

	// For testing GDI GetPixel speed, we need a HDC for the source bitmap
	HBITMAP hSrcBmp = NULL;
	HDC     hSrcDC  = NULL;
	HGDIOBJ hSrcOld = NULL;

	if ( method==method_gdi )
	{
		hSrcBmp = CreateDIBSection(NULL, m_pBMI, DIB_RGB_COLORS, (void **) & pBits, NULL, NULL);
		assert(hSrcBmp);

		hSrcDC  = CreateCompatibleDC(NULL);
		hSrcOld = SelectObject(hSrcDC, hSrcBmp);

		// copy pixels from DIB to source DIB section
		DrawDIB(hSrcDC, 0, 0, m_nWidth, m_nHeight, 0, 0, m_nWidth, m_nHeight, SRCCOPY);
	}

	// clear DIB section to background color
	HDC     hDstDC  = CreateCompatibleDC(NULL);
	HGDIOBJ hDstOld = SelectObject(hDstDC, hBitmap);

	HBRUSH hBrush = CreateSolidBrush(crBack);
	RECT rect = { 0, 0,  destwidth, destheight };
	FillRect(hDstDC, & rect, hBrush);
	DeleteObject(hBrush);

	KDIB destDIB;
	destDIB.AttachDIB(dest.GetBMI(), pBits, 0);

	POINT P[3] = { { x0-xmin, y0-ymin }, { x1-xmin, y1-ymin }, { x2-xmin, y2-ymin } };

	dibtick = GetTickCount();
	
	if ( (m_nBitCount<=8) && (method==method_24bpp) )
		method = method_direct;

	switch ( method )
	{
		case method_gdi:
			destDIB.PlgBltGetPixel(P, hSrcDC, 0, 0, m_nWidth, m_nHeight, hDstDC);
			break;   

		case method_direct:	
			destDIB.PlgBlt(P, this, 0, 0, m_nWidth, m_nHeight);
			break;   

		case method_24bpp:
			destDIB.PlgBlt24(P, this, 0, 0, m_nWidth, m_nHeight);
			break;
	}

	dibtick = GetTickCount() - dibtick;

	SelectObject(hDstDC, hDstOld);
	DeleteObject(hDstDC);

	if ( method==method_gdi )
	{
		SelectObject(hSrcDC, hSrcOld);

		DeleteObject(hSrcDC);
		DeleteObject(hSrcBmp);
	}

	return hBitmap;
}
Example #8
0
LRESULT CALLBACK
WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
	PAINTSTRUCT	ps;
	HDC		hdc;
#if CLIENT3D | IMAGE | GRAPH3D
	RECT		rc;
#endif
#if GRAPH3D
	static int	countup = 1;
	int		id;
	static vec1 	gx, gy;
#endif
#if TIMERDEMO
	static POINT	mousept;
#endif
#if ARCDEMO
	static int	startdegrees = 0;
	static int	enddegrees = 30;
#endif

	switch( msg) {
#if TIMERDEMO
	case WM_CREATE:
		SetTimer(hwnd, 1, 100, NULL);
		mousept.x = 60;
		mousept.y = 20;
		break;

	case WM_TIMER:
#if GRAPH3D
		GetClientRect(hwnd, &rc);
		if(countup) {
			mousept.y += 20;
			if(mousept.y >= rc.bottom) {
				mousept.y -= 20;
				countup = 0;
			}
		} else {
			mousept.y -= 20;
			if(mousept.y < 20) {
				mousept.y += 20;
				countup = 1;
			}
		}
		SendMessage(hwnd, WM_MOUSEMOVE, 0,
			MAKELONG(mousept.x, mousept.y));
#endif
#if ARCDEMO
		startdegrees += 10;
		if(startdegrees >= 360)
			startdegrees = 0;
		enddegrees += 15;
		if(enddegrees >= 360)
			enddegrees = 0;
		InvalidateRect(hwnd, NULL, TRUE);
#endif
		break;

	case WM_DESTROY:
		KillTimer(hwnd, 1);
		break;
#endif /* TIMERDEMO*/
	case WM_SIZE:
		break;

	case WM_MOVE:
		break;

#if CLIENT3D
	case WM_SETFOCUS:
		PostMessage((HWND)wp, WM_PAINT, 0, 0L);
		break;

	case WM_KILLFOCUS:
		PostMessage((HWND)wp, WM_PAINT, 0, 0L);
		break;
	case WM_ERASEBKGND:
		if(GetFocus() != hwnd)
			return DefWindowProc(hwnd, msg, wp, lp);
		return 1;
#endif
#if GRAPH3D
	case WM_ERASEBKGND:
		if((GetWindowLong(hwnd, GWL_ID) & 03) == 1)
			return 1;
		return DefWindowProc(hwnd, msg, wp, lp);
#endif
	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);

#if CLIENT3D
		if(GetFocus() == hwnd) {
			GetClientRect(hwnd, &rc);
			Draw3dShadow(hdc, rc.left, rc.top,
				rc.right-rc.left, rc.bottom-rc.top,
				GetSysColor(COLOR_3DDKSHADOW),
				GetSysColor(COLOR_3DLIGHT));
			InflateRect(&rc, -1, -1);
			FillRect(hdc, &rc, GetStockObject(GRAY_BRUSH));
		}
#endif
#if IMAGE
		GetClientRect(hwnd, &rc);
		DrawDIB(hdc, rc.left+2, rc.top+2, image2);
#endif
#if ARCDEMO
{
	int x, y, w, h;
	RECT rc;

	if(hdc != NULL) {
		GetWindowRect(hwnd, &rc);
		rc.top += 13;
		InflateRect(&rc, -3, -3);
		/*Ellipse(hdc, 0, 0, rc.right-rc.left, rc.bottom-rc.top);*/
		/*Arc(hdc, 0, 0, rc.right-rc.left, rc.bottom-rc.top, 0,0, 0,0);*/
		/*Pie(hdc, 0, 0, rc.right-rc.left, rc.bottom-rc.top, 0,0, 0,0);*/

		x = rc.left;
		y = rc.top;
		w = rc.right - rc.left;
		h = rc.bottom - rc.top;
		w += 10;
		GdSetForeground(GdFindColor(RGB(0,255,0)));
		GdArcAngle(hdc->psd, x+w/2, y+h/2, w/2, h/2, startdegrees*64,
			enddegrees*64, MWPIE);
		GdSetForeground(GdFindColor(RGB(0,0,0)));
		GdArcAngle(hdc->psd, x+w/2, y+h/2, w/2, h/2, startdegrees*64,
			enddegrees*64, MWARCOUTLINE);
		/*GdSetForeground(GdFindColor(RGB(255,255,255)));*/
		/*GdPoint(hdc->psd, x+w/2, y+h/2);*/
	}
	EndPaint(hwnd, &ps);
	break;
}
#endif /* ARCDEMO*/
#if GRAPH3D
		id = (int)GetWindowLong(hwnd, GWL_ID) & 03;
		init3(hdc, id == 1? hwnd: NULL);
		switch(id) {
		case 0:
			rose(1.0, 7, 13);
			break;
		case 1:
			/*look3(0.5, 0.7, 1.5);*/
			/*look3(0.2, -2 * gy, 1.0+gx);*/
			look3(-2 * gx, -2 * gy, 1.2);
			drawgrid(-8.0, 8.0, 10, -8.0, 8.0, 10);
			break;
		case 2:
			setcolor3(BLACK);
			circle3(1.0);
			break;
		case 3:
			setcolor3(BLUE);
			daisy(1.0, 20);
			break;
		}

#if CLIPDEMO
		if(id == 1) {
			HRGN	hrgn, hrgn2;

			/* create circular clip region for effect*/
			GetClientRect(hwnd, &rc);
			InflateRect(&rc, -80, -80);
			switch((int)GetWindowLong(hwnd, GWL_ID)) {
			default:
				hrgn = CreateEllipticRgnIndirect(&rc);
				break;
			case 5:
				hrgn = CreateRoundRectRgn(rc.left, rc.top,
					rc.right, rc.bottom, 100, 100);
				break;
			case 1:
				hrgn = CreateRectRgnIndirect(&rc);
				break;
			}

			/* erase background, clip out blit area*/
			GetClientRect(hwnd, &rc);
			hrgn2 = CreateRectRgnIndirect(&rc);
			SelectClipRgn(hdc, hrgn2);
			ExtSelectClipRgn(hdc, hrgn, RGN_XOR);
			DeleteObject(hrgn2);

			GetClientRect(hwnd, &rc);
			FillRect(hdc, &rc, GetStockObject(BLACK_BRUSH));

			/* clip in only blit area*/
			SelectClipRgn(hdc, hrgn);
			DeleteObject(hrgn);
		}
#endif /* CLIPDEMO*/

		paint3(hdc);

#endif /* GRAPH3D*/
		EndPaint(hwnd, &ps);
		break;

	case WM_LBUTTONDOWN:
		break;

	case WM_MOUSEMOVE:
#if GRAPH3D
		if((GetWindowLong(hwnd, GWL_ID) & 03) == 1) {
			POINT pt;

			POINTSTOPOINT(pt, lp);
			GetClientRect(hwnd, &rc);
			gx = (vec1)pt.x / rc.right;
			gy = (vec1)pt.y / rc.bottom;
			InvalidateRect(hwnd, NULL, FALSE);
			mousept.x = pt.x;
			mousept.y = pt.y;
		}
#endif
		break;

	case WM_LBUTTONUP:
		break;

	case WM_RBUTTONDOWN:
		break;

	default:
		return DefWindowProc( hwnd, msg, wp, lp);
	}
	return( 0);
}
Example #9
0
/*
 * This procedure implements the messages passed by the window
 * manager for default processing on behalf of the window.
 */
LRESULT WINAPI
DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	HDC		hdc;
	RECT		rc;
	DWORD		dwStyle;
	HBRUSH		hbr;
	HPEN		hpen, holdpen;
	PAINTSTRUCT	ps;
	POINT		curpt;
	int 		x, y;
	HWND		wp;
	HWND		oldActive;
	COLORREF	crCaption;
	LPNCCALCSIZE_PARAMS lpnc;
	CHAR		szTitle[64];
	static POINT 	startpt;

	switch(msg) {
	case WM_NCCALCSIZE:
		/* calculate client rect from passed window rect in rgrc[0]*/
		lpnc = (LPNCCALCSIZE_PARAMS)lParam;
		dwStyle = GetWindowLong(hwnd, GWL_STYLE);
		if(dwStyle & WS_BORDER) {
			if((dwStyle & WS_CAPTION) == WS_CAPTION) {
				InflateRect(&lpnc->rgrc[0],
					-mwSYSMETRICS_CXFRAME,
					-mwSYSMETRICS_CYFRAME);
				lpnc->rgrc[0].top += mwSYSMETRICS_CYCAPTION + 1;
			} else
				InflateRect(&lpnc->rgrc[0], -1, -1);
		}
		break;

	case WM_NCPAINT:
		/* repaint all non-client area*/
		dwStyle = GetWindowLong(hwnd, GWL_STYLE);

		if(dwStyle & WS_BORDER) {
			hdc = GetWindowDC(hwnd);
			GetWindowRect(hwnd, &rc);

			if((dwStyle & WS_CAPTION) == WS_CAPTION) {
				/* draw 2-line 3d border around window*/
				Draw3dOutset(hdc, rc.left, rc.top,
					rc.right-rc.left, rc.bottom-rc.top);
				InflateRect(&rc, -2, -2);

				/* draw 1-line inset inside border*/
				hpen = CreatePen(PS_SOLID, 1,
					GetSysColor(COLOR_BTNFACE));
				holdpen = SelectObject(hdc, hpen);
				SelectObject(hdc, GetStockObject(NULL_BRUSH));
				Rectangle(hdc, rc.left, rc.top, rc.right,
					rc.bottom);
				InflateRect(&rc, -1, -1);

				/* fill caption*/
				rc.bottom = rc.top + mwSYSMETRICS_CYCAPTION;
				crCaption = GetActiveWindow()==hwnd?
					GetSysColor(COLOR_ACTIVECAPTION):
					GetSysColor(COLOR_INACTIVECAPTION);
				hbr = CreateSolidBrush(crCaption);
				FillRect(hdc, &rc, hbr);
				DeleteObject(hbr);

				/* draw 1 line under caption*/
				MoveToEx(hdc, rc.left, rc.bottom, NULL);
				LineTo(hdc, rc.right, rc.bottom);
				DeleteObject(SelectObject(hdc, holdpen));

				/* draw caption text*/
				if(GetWindowText(hwnd, szTitle,
				   sizeof(szTitle))) {
					SetBkMode(hdc, TRANSPARENT);
					/* set background color even though
					 * transparent in case GdArea is used
					 * to draw text which compares
					 * gr_foreground != gr_background
					 * when transparent...
					 */
					SetBkColor(hdc, crCaption);
					SetTextColor(hdc,
						GetActiveWindow()==hwnd?
						GetSysColor(COLOR_CAPTIONTEXT):
						GetSysColor(COLOR_INACTIVECAPTIONTEXT));
					SelectObject(hdc,
					    GetStockObject(DEFAULT_GUI_FONT));
					GetWindowRect(hwnd, &rc);
					TextOut(hdc, rc.left+4, rc.top+2,
						szTitle, strlen(szTitle));
				}

				/* draw close box*/
				GetCloseBoxRect(hwnd, &rc);
				/*DrawDIB(hdc, rc.right-XSIZE_CLOSEBOX-3,
					rc.top+3, &image_close4);*/
				Draw3dBox(hdc, rc.left, rc.top,
					rc.right-rc.left, rc.bottom-rc.top,
					GetSysColor(COLOR_BTNHIGHLIGHT),
					GetSysColor(COLOR_WINDOWFRAME));
				InflateRect(&rc, -1, -1);
				hbr = CreateSolidBrush(
					GetSysColor(COLOR_BTNFACE));
				FillRect(hdc, &rc, hbr);
				DeleteObject(hbr);

				InflateRect(&rc, -1, -1);
				MoveToEx(hdc, rc.left, rc.top, NULL);
				LineTo(hdc, rc.right-1, rc.bottom-1);
				MoveToEx(hdc, rc.left, rc.bottom-1, NULL);
				LineTo(hdc, rc.right-1, rc.top);
			} else {
				SelectObject(hdc, GetStockObject(NULL_BRUSH));
				Rectangle(hdc, rc.left, rc.top, rc.right,
					rc.bottom);
			}
			ReleaseDC(hwnd, hdc);
		}
		break;

	case WM_NCHITTEST:
		/* if system is dragging a window, always return caption*/
		if(dragwp)
			return HTCAPTION;

		/* Determine what part of the window the mouse is over*/
		POINTSTOPOINT(curpt, lParam);

		if(PtInRect(&hwnd->clirect, curpt))
			return HTCLIENT;

		if(PtInRect(&hwnd->vscroll.rc, curpt))
			return HTVSCROLL;
		if(PtInRect(&hwnd->hscroll.rc, curpt))
			return HTHSCROLL; 

		dwStyle = GetWindowLong(hwnd, GWL_STYLE);
		if((dwStyle & WS_CAPTION) == WS_CAPTION) {
			GetCloseBoxRect(hwnd, &rc);
			if(PtInRect(&rc, curpt))
				return HTCLOSE;

			GetWindowRect(hwnd, &rc);
			InflateRect(&rc, -2, -2);
			rc.bottom = rc.top + mwSYSMETRICS_CYCAPTION;
			if(PtInRect(&rc, curpt))
				return HTCAPTION;

			GetWindowRect(hwnd, &rc);
			InflateRect(&rc, -2, -2);
			rc.top += mwSYSMETRICS_CYCAPTION;
			if(PtInRect(&rc, curpt))
				return HTCLIENT;

			return HTBORDER;
		}
		return HTNOWHERE;

	case WM_NCLBUTTONDOWN:
		/* Handle default actions for mouse down on window*/
		if(wParam == HTCLOSE) {
			SendMessage(hwnd, WM_CLOSE, 0, 0L);
			break;
		}

		/* set focus on mouse down, repaint if necessary*/
		oldActive = GetActiveWindow();
		if(wParam == HTCLIENT || wParam == HTVSCROLL ||
		   wParam == HTHSCROLL)
			/* activate and raise window if in client area*/
			/* kaffe port requires this commented out*/
			SetForegroundWindow(hwnd);
		else {
			/* otherwise just change focus window, same z order*/
			/* this will activate it's top level parent*/
			SetFocus(hwnd);
		}
		/* repaint captions now because of activation change*/
		UpdateWindow(oldActive);
		UpdateWindow(hwnd);

		if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
			MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
			break;
		}

		/* start window drag if in caption area*/
		if(wParam == HTCAPTION && hwnd != rootwp) {
			POINTSTOPOINT(startpt, lParam);
			if(!(GetWindowLong(hwnd, GWL_STYLE) & WS_MAXIMIZE))
				dragwp = hwnd;
			SetRectEmpty(&lastrc);	/* XORMOVE only*/
		}
		break;

	case WM_NCMOUSEMOVE:
		if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
			MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
			break;
		}

		/* drag window with mousemove after mousedown*/
		if(dragwp == hwnd) {
			POINTSTOPOINT(curpt, lParam);
			x = curpt.x - startpt.x;
			y = curpt.y - startpt.y;

			if(mwERASEMOVE) {
				GetWindowRect(hwnd, &rc);
				MoveWindow(hwnd, rc.left+x, rc.top+y,
					rc.right-rc.left, rc.bottom-rc.top,
					TRUE);
				startpt = curpt;
			} else
				DrawXORFrame(hwnd, x, y, TRUE);
		}
		break;

	case WM_NCLBUTTONUP:
		/* stop window drag*/
		if(dragwp == hwnd) {
			dragwp = NULL;

			if(mwERASEMOVE) {
				/*
				 * User stopped moving window, repaint 
				 * windows previously queued for painting.
				 */
				for(wp=listwp; wp; wp=wp->next)
					if(wp->gotPaintMsg == PAINT_DELAYPAINT)
					    wp->gotPaintMsg = PAINT_NEEDSPAINT;
			} else {
				POINTSTOPOINT(curpt, lParam);
				x = curpt.x - startpt.x;
				y = curpt.y - startpt.y;
				DrawXORFrame(hwnd, x, y, FALSE);
				GetWindowRect(hwnd, &rc);
				MoveWindow(hwnd, rc.left+x, rc.top+y,
				    rc.right-rc.left, rc.bottom-rc.top, TRUE);
			}
		}

		if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
			MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
			break;
		}
		break;

	case WM_NCLBUTTONDBLCLK:
		if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
			MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
			break;
		}

		/* maximize/restore processing*/
		if(wParam != HTCAPTION)
			break;

		if((hwnd->style & WS_CAPTION) == WS_CAPTION) {
			if(hwnd->style & WS_MAXIMIZE) {
				rc = hwnd->restorerc;
				MoveWindow(hwnd, rc.left, rc.top,
					rc.right-rc.left, rc.bottom-rc.top,
					TRUE);
				hwnd->style &= ~WS_MAXIMIZE;
			} else {
				hwnd->restorerc = hwnd->winrect;
				GetWindowRect(rootwp, &rc);
				MoveWindow(hwnd, -mwSYSMETRICS_CXFRAME,
					-mwSYSMETRICS_CYFRAME,
					rc.right+2*mwSYSMETRICS_CXFRAME,
					rc.bottom+2*mwSYSMETRICS_CYFRAME, TRUE);
				hwnd->style |= WS_MAXIMIZE;
			}
		}
		break;

	case WM_GETTEXTLENGTH:
		/* Get window text length.  This routine requires
		 * knowledge of the internal window structure
		 */
		return strlen(hwnd->szTitle);

	case WM_GETTEXT:
		/* Get window text.  This routine requires
		 * knowledge of the internal window structure
		 */
		return strzcpy((LPSTR)lParam, hwnd->szTitle, wParam);

	case WM_SETTEXT:
		/* Set window text.  This routine requires
		 * knowledge of the internal window structure.
		 * Note that setting text doesn't invalidate the window.
		 */
		strzcpy(hwnd->szTitle, (LPSTR)lParam, sizeof(hwnd->szTitle));
		return TRUE;

	case WM_CLOSE:
		DestroyWindow(hwnd);
		if(hwnd == rootwp)
			PostQuitMessage(0);
		break;

	case WM_ERASEBKGND:
		/* erase background with class background brush*/
		hbr = (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND);
		if(!hbr)
			return 0;
		/* don't exclude update region*/
		hdc = GetDCEx(hwnd, NULL, DCX_DEFAULTCLIP);
		FillRect(hdc, NULL, hbr);
		ReleaseDC(hwnd, hdc);
		return 1;

	case WM_PAINT:
		/* required to send erasebkgnd for desktop window*/
		hdc = BeginPaint(hwnd, &ps);

		/* draw desktop wallpaper*/
		if(hwnd == rootwp && pImageWallpaper) {
			GetWindowRect(hwnd, &rc);
			DrawDIB(hdc,
				(rc.right-rc.left-pImageWallpaper->width)/2,
				(rc.bottom-rc.top-pImageWallpaper->height)/2,
				pImageWallpaper);
		}

		EndPaint(hwnd, &ps);
		break;
	}
	return 0;
}