⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 window.cpp

📁 虚拟打印机
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * * window.cpp *   Copyright (C) 2006 Michael H. Overlin   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA      Contact at poster_printer@yahoo.com */#include "window.h"#include "gdiutils.h"#include "mathutils.h"#include "sprite.h"// **// ** PUBLIC// **Window::Window(HINSTANCE hinst, HWND hwnd, PaintMode pm) {	m_hinst = hinst;	m_hwnd = hwnd;	m_ptScroll.x = m_ptScroll.y = 0;	::ZeroMemory(&m_rScroll, sizeof(m_rScroll));	m_pm = pm;	m_bEraseBufferBkg = FALSE;	::GetClientRect(m_hwnd, &m_rClient);	m_hrgnUpdate = ::CreateRectRgn(0,0,0,0);	m_hrgnEmpty = ::CreateRectRgn(0,0,0,0);	m_hbmpBuffer = NULL;	this->m_hbmpBuffer = NULL;	this->m_bHasBkClr = FALSE;	this->m_bkClr = RGB(0xff, 0xff, 0xff);	this->SizePaintBuffer();	// SPRITE	m_ps = NULL;	m_bUpdateSpriteWithWindow = FALSE;}Window::~Window() {	if (m_hrgnUpdate != NULL) {		::DeleteObject(m_hrgnUpdate);	}	if (m_hrgnEmpty != NULL) {		::DeleteObject(m_hrgnEmpty);	}	if (m_hbmpBuffer != NULL) {		::DeleteObject(m_hbmpBuffer);	}}BOOL Window::InvalidateRect(const RECT& r, BOOL bErase) {	BOOL bRetValue = TRUE;	switch(m_pm) {	case Window::ePaintDirect:		bRetValue = ::InvalidateRect(m_hwnd, &r, bErase);		break;	case Window::ePaintBuffered: {		// 7/7 NOTE:		// DEBUG/FIX THE "ERASE" SETTINGS MAY DIFFER FROM ONE REGION TO ANOTHER		// IF WE WANTED, WE COULD KEEP TRACK OF A SEPARATE SUB-REGION THAT NEEDS TO BE ERASED		// RATHER THAN TURNING ERAASING ON FOR THE ENTIRE UPDATE REGION		if (bErase) {			m_bEraseBufferBkg = TRUE;		}		HRGN hrgnTemp = ::CreateRectRgn(r.left, r.top, r.right, r.bottom);		::CombineRgn(m_hrgnUpdate, m_hrgnUpdate, hrgnTemp, RGN_OR);		::DeleteObject(hrgnTemp);		::InvalidateRect(m_hwnd, &r, FALSE);		bRetValue = TRUE;	} break;	default:		ASSERTFAIL();		break;	}	return bRetValue;}BOOL Window::InvalidateRgn(HRGN hrgn, BOOL bErase) {	BOOL bRetValue = TRUE;	switch(m_pm) {	case Window::ePaintDirect:		bRetValue = ::InvalidateRgn(m_hwnd, hrgn, bErase);		break;	case Window::ePaintBuffered: {		if (bErase) {			m_bEraseBufferBkg = TRUE;		}		::CombineRgn(m_hrgnUpdate, m_hrgnUpdate, hrgn, RGN_OR);		::InvalidateRgn(m_hwnd, hrgn, FALSE); 	} break;	default:		ASSERTFAIL();		break;	}	return TRUE;}void Window::DoUpdateDirectLayer(UpdateDirectLayer& dp) {	HDC hdc = this->GetDC();	dp.PaintDirect(hdc);	this->ReleaseDC(hdc);}void Window::SetSprite(Sprite *ps) {	m_ps = ps;}// THIS COULD BE DONE AS A DIRECT DRAW, YES ?void Window::DoUpdateSprite(void) {	HDC hdc = ::GetDC(m_hwnd);	Window::BackBufferDCInfo bbdi;	HDC hdcMem = this->CreateBackBufferDC(bbdi, hdc);	HRGN hrgnUpdate = ::CreateEmptyRgn();	m_ps->Update(hdcMem, hrgnUpdate);	//CLIPPING DEVICE VS LOGICAL COORDS??	::SelectClipRgn(hdc, hrgnUpdate);	::BitBlt(hdc, 0, 0, RW(m_rClient), RH(m_rClient), hdcMem, 0, 0, SRCCOPY);	this->PaintDirectLayer(hdc);	this->DeleteBackBufferDC(bbdi);	::ReleaseDC(m_hwnd, hdc);}void Window::SetBackgroundColor(COLORREF clr) {	if (clr != m_bkClr) {		m_bHasBkClr = TRUE;		m_bkClr = clr;		this->InvalidateRect(this->m_rClient, TRUE);	}}// NOTE:  IMPLEMENTATION ASSUMES THAT rSrcScroll REMAINS FIXED UNTIL A WM_PAINT OCCURS//        ALSO, ONLY BEEN TESTED FOR THE ePaintBuffered CASE//        ALSO, IT ASSUMES THAT IF THERE IS A SPRITE IT IS ENTIRELY WITHIN THE REGION BEING//		  SCROLLED -- SO IMPLEMENTATION IS NOT REALLY COMPLETE YET, BUT DOES WORK UNDER THESE ASSUMPTIONSvoid Window::ScrollWindow(int dx, int dy, const RECT& rSrcScroll) {	switch(m_pm) {	case ePaintDirect:		::ScrollWindowEx(m_hwnd, dx, dy, &rSrcScroll, NULL, NULL, NULL, SW_INVALIDATE | SW_ERASE);		// DEBUG/FIX		if (m_ps != NULL) {			POINT ptDelta = { dx, dy };			m_ps->Scroll(ptDelta);		}		break;	case ePaintBuffered: 		m_ptScroll.x += dx;		m_ptScroll.y += dy;		m_rScroll = rSrcScroll;		//7/7 DEBUG/FIX EXTRA CHANGE AFTER WORKING		//::InvalidateRect(m_hwnd, &rSrcScroll, TRUE);		::InvalidateRect(m_hwnd, &rSrcScroll, FALSE);		break;	default:		ASSERTFAIL();		break;	}}HWND Window::AddArgumentAsNotifyTarget(HWND hwnd) {	this->m_vhwndNotify.push_back(hwnd);	return m_hwnd;}HWND Window::AddToArgumentsNotifyTargetList(Window *pw) {	return pw->AddArgumentAsNotifyTarget(m_hwnd);}LPTSTR Window::GetWindowText(void) const {	LPTSTR lptstr = ::MyGetWindowText(m_hwnd);	return lptstr;}LRESULT Window::SendNotification(IN HWND hwnd, NMHDR *pnmh) { 	LRESULT lRetValue =  ::SendMessage(hwnd, WM_NOTIFY, pnmh->idFrom, (LPARAM) pnmh); 	for(uint ui = 0; ui < m_vhwndNotify.size(); ++ui) {		HWND hwndTarget = m_vhwndNotify[ui];		::SendMessage(hwndTarget, WM_NOTIFY, pnmh->idFrom, (LPARAM) pnmh); 	}	return lRetValue;}LRESULT Window::SendNotification(IN UINT code) { 	NMHDR nmh = { m_hwnd, this->GetDlgCtrlID(),  code }; 	LRESULT lRetValue = this->SendNotification(GetParent(), &nmh);	return lRetValue;}// **// ** PROTECTED// **void Window::Paint(HDC hdc) {	// DO NOTHING}void Window::PaintDirectLayer(HDC hdc) {	// DO NOTHING}void Window::CursorMsg(OUT MSGRESULT& mr, UINT msg, WPARAM wParam, LPARAM lParam) {	mr.bProcessed = FALSE;}void Window::KeyboardMsg(OUT MSGRESULT& mr, UINT msg, WPARAM wParam, LPARAM lParam) {	mr.bProcessed = FALSE;}void Window::MouseMsg(OUT MSGRESULT& mr, UINT msg, WPARAM wParam, LPARAM lParam) {	mr.bProcessed = FALSE;}void Window::NotificationMsg(OUT MSGRESULT& mr, UINT msg, WPARAM wParam, LPARAM lParam) {	mr.bProcessed = FALSE;	switch(msg) {	case WM_SIZE: 		::GetClientRect(m_hwnd, &m_rClient);		this->SizePaintBuffer();		break;	default:		break;	}}void Window::NotifyMsg(OUT MSGRESULT& mr, WPARAM wParam, LPARAM lParam) {	mr.bProcessed = FALSE;}void Window::PaintMsg(OUT MSGRESULT& mr, UINT msg, WPARAM wParam, LPARAM lParam) {	if (m_pm == Window::ePaintBuffered && (m_ptScroll.x != 0 || m_ptScroll.y != 0)) {		int dx = m_ptScroll.x;		int dy = m_ptScroll.y;		m_ptScroll.x = m_ptScroll.y = 0;		RECT rSrcScroll = m_rScroll;		HRGN hrgnTemp = ::CreateRectRgnIndirect(&rSrcScroll);		RECT rTemp = rSrcScroll;		::OffsetRect(&rTemp, dx, dy);		HRGN hrgnTemp2 = ::CreateRectRgnIndirect(&rTemp);		HRGN hrgnTemp3 = ::CreateRectRgn(0,0,0,0);		::CombineRgn(hrgnTemp3, hrgnTemp, hrgnTemp2, RGN_DIFF);		::CombineRgn(m_hrgnUpdate, m_hrgnUpdate, hrgnTemp3, RGN_OR);		//7/7 DEBUG/FIX EXTRA CHANGE AFTER WORKING -- THIS ISN'T NEEDED		//::InvalidateRect(m_hwnd, &rSrcScroll, TRUE);		m_bEraseBufferBkg = TRUE; // ??		::DeleteObject(hrgnTemp);		::DeleteObject(hrgnTemp2);		::DeleteObject(hrgnTemp3);		Window::BackBufferDCInfo bbdi;		HDC hdcMem = this->CreateBackBufferDC(bbdi, NULL);		SIZE sz = { RW(rSrcScroll), RH(rSrcScroll) };		int x1 = max(dx, 0);		int y1 = max(dy, 0);		int x2 = - min(dx, 0);		int y2 = - min(dy, 0);		int adx = abs(dx);		int ady = abs(dy);		::BitBlt(hdcMem, 			rSrcScroll.left + x1, rSrcScroll.top + y1, 			sz.cx - adx, sz.cy - ady, 			hdcMem, rSrcScroll.left + x2, rSrcScroll.top + y2, SRCCOPY);		this->DeleteBackBufferDC(bbdi);		if (m_ps != NULL) {			POINT ptDelta = { dx, dy };			m_ps->Scroll(ptDelta);			//HRGN hrgn = m_ps->GetUpdateRegion();		}	}	switch(msg) {	case WM_ERASEBKGND:		switch(m_pm) {		case Window::ePaintDirect: 			if (this->m_bHasBkClr) {				HDC hdc = (HDC) wParam;				::FillSolidColor(hdc, m_rClient, m_bkClr);				mr.lRetValue = 0;				mr.bProcessed = TRUE;			}			break;		case Window::ePaintBuffered:			mr.lRetValue = 0;			mr.bProcessed = TRUE;			break;		default:			ASSERTFAIL();			break;		}		break;	case WM_PAINT: {		HRGN hrgnMeta = NULL;		switch(m_pm) {		case ePaintDirect:			::GetUpdateRgn(m_hwnd, m_hrgnUpdate, FALSE);			break;		case ePaintBuffered:			hrgnMeta = ::CreateRectRgn(0,0,0,0);			::GetUpdateRgn(m_hwnd, hrgnMeta, FALSE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -