/* Written by Bogdan Ledwig (bogdanle@opole.mtl.pl). Copyright © 1999 Bogdan Ledwig. All Rights Reserved. This code may be used in compiled form in any way you wish. This file may be redistributed unmodified by any means PROVIDING it is not sold for profit without the authors written consent, and providing that this notice and the authors name is included. If the source code is used in any commercial application then an email letting me know that you are using it would be nice. However, this code may not be sold as a part of any commercial library in compiled or source form. In any other cases the code is free to whoever wants it anyway. This software is provided "as is" without express or implied warranty. Use it at you own risk! The author accepts no liability for any damages to your computer or data this product may cause. */ // Modified by Larry Leonard, Definitive Solutions, Inc. #include "StdAfx.h" #include "MyMdiClient.h" #include "MainFrm.h" #include "MyRegistry.h" #include "Generic.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // Defines #define REG_KEY_NAME "Software\\Your Company Name\\Your Product Name\\MDIClient" BEGIN_MESSAGE_MAP(MyMdiClient, CWnd) //{{AFX_MSG_MAP(MyMdiClient) ON_WM_PAINT() ON_WM_DESTROY() ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_LBUTTONDOWN() ON_WM_RBUTTONDOWN() ON_WM_MOUSEMOVE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // MyMdiClient // Constructor. MyMdiClient::MyMdiClient() { Reset(); } // Destructor. /* virtual */ MyMdiClient::~MyMdiClient() { } // void MyMdiClient::SetOrigin(int x, int y, bool bRedraw) { VALIDATE; _ASSERTE(0 <= x); _ASSERTE(0 <= y); m_ptOrigin.x = x; m_ptOrigin.y = y; if (bRedraw && IsWindow(m_hWnd)) { Invalidate(); } } // void MyMdiClient::SetOrigin(const CPoint& point, bool bRedraw) { VALIDATE; m_ptOrigin = point; if (bRedraw && IsWindow(m_hWnd)) { Invalidate(); } } // void MyMdiClient::PreSubclassWindow() { VALIDATE; CWnd::PreSubclassWindow(); RestoreState(); } // void MyMdiClient::Reset() { VALIDATE; m_ptOrigin.x = m_ptOrigin.y = 0; m_sizImage.cx = m_sizImage.cy = 0; m_eDisplayMode = MyMdiClient::dispTile; m_sFileName.Empty(); SetBkColor(::GetSysColor(COLOR_APPWORKSPACE)); m_bitmap.DeleteObject(); if (IsWindow(m_hWnd)) { Invalidate(); } } // bool MyMdiClient::SetBitmap(LPCTSTR lpszFileName, UINT uFlags) { VALIDATE; _ASSERTE(lpszFileName); bool bReturn(false); // Clear it out. if (! lpszFileName || 0 == lstrlen(lpszFileName)) { bReturn = true; COLORREF crBack(m_crBackground); Reset(); SetBkColor(crBack); } else { // Set the bitmap. HANDLE handle(::LoadImage(AfxGetInstanceHandle(), lpszFileName, IMAGE_BITMAP, 0, 0, uFlags | LR_LOADFROMFILE)); if (handle) { bReturn = true; m_bitmap.DeleteObject(); VERIFY(m_bitmap.Attach((HBITMAP)handle)); if (IsWindow(m_hWnd)) { Invalidate(); } m_sFileName = lpszFileName; BITMAP bi; ::ZeroMemory(&bi, sizeof(bi)); m_bitmap.GetBitmap(&bi); m_sizImage.cx = bi.bmWidth; m_sizImage.cy = bi.bmHeight; } else { DOMYLOG ("*** File '%s' does not exist - m_sFileName will NOT be set!\n", lpszFileName); } } return bReturn; } // bool MyMdiClient::SetBitmap(UINT nBitmapID, COLORMAP* pClrMap, int nCount) { VALIDATE; ASSERT_NULL_OR_POINTER(pClrMap, COLORMAP); VERIFY(m_bitmap.DeleteObject()); // Load mapped if (pClrMap) { if (! m_bitmap.LoadMappedBitmap(nBitmapID, 0, pClrMap, nCount)) { return false; } } else { // Load normal. if (! m_bitmap.LoadBitmap(nBitmapID)) { return false; } } BITMAP bi; ::ZeroMemory(&bi, sizeof(bi)); m_bitmap.GetBitmap(&bi); m_sizImage.cx = bi.bmWidth; m_sizImage.cy = bi.bmHeight; if (IsWindow(m_hWnd)) { Invalidate(); } return true; } // void MyMdiClient::SetBkColor(COLORREF clrValue) { VALIDATE; m_crBackground = clrValue; m_brush.DeleteObject(); VERIFY(m_brush.CreateSolidBrush(m_crBackground)); if (IsWindow(m_hWnd)) { Invalidate(); } } // void MyMdiClient::SetDisplayMode(MyMdiClient::DisplayModesEnum eDisplayMode) { VALIDATE; m_eDisplayMode = eDisplayMode; if (IsWindow(m_hWnd)) { Invalidate(); } } // void MyMdiClient::SaveState() const { VALIDATE; MyRegistry reg(HKEY_CURRENT_USER, REG_KEY_NAME); VERIFY(reg.SaveValueInt("DisplayMode", m_eDisplayMode)); VERIFY(reg.SaveValueInt("BkColor", m_crBackground)); VERIFY(reg.SaveValueString("FileName", m_sFileName)); VERIFY(reg.SaveValueInt("OriginX", m_ptOrigin.x)); VERIFY(reg.SaveValueInt("OriginY", m_ptOrigin.y)); } // void MyMdiClient::RestoreState() { VALIDATE; MyRegistry reg(HKEY_CURRENT_USER, REG_KEY_NAME, /* bCreate */ false); if (reg.IsOpen()) { int nMode(0); VERIFY(reg.ReadValueInt("DisplayMode", nMode)); m_eDisplayMode = static_cast (nMode); VERIFY(reg.ReadValueLong("OriginX", m_ptOrigin.x)); VERIFY(reg.ReadValueLong("OriginY", m_ptOrigin.y)); COLORREF crBack(0); VERIFY(reg.ReadValueDWord("BkColor", crBack)); SetBkColor(crBack); CString sFilename; VERIFY(reg.ReadValueString("FileName", sFilename)); if (sFilename.GetLength()) { VERIFY(SetBitmap(sFilename)); } } } // void MyMdiClient::OnPaint() { VALIDATE; CPaintDC dc(this); // If there is a bitmap currently set. if (NULL != (HBITMAP) m_bitmap) { CRect rcClient; GetClientRect(rcClient); switch (m_eDisplayMode) { case MyMdiClient::dispCustom: { CBitmap bmp; VERIFY(bmp.CreateCompatibleBitmap(&dc, rcClient.right, rcClient.bottom)); CDC memDC; VERIFY(memDC.CreateCompatibleDC(&dc)); VERIFY(memDC.SelectObject(&bmp)); memDC.FillRect(&(dc.m_ps.rcPaint), &m_brush); VERIFY(memDC.DrawState(m_ptOrigin, m_sizImage, &m_bitmap, DST_BITMAP | DSS_NORMAL)); VERIFY(dc.BitBlt(0, 0, rcClient.right, rcClient.bottom, &memDC, 0, 0, SRCCOPY)); } break; case MyMdiClient::dispCenter: { CBitmap bmp; VERIFY(bmp.CreateCompatibleBitmap(&dc, rcClient.right, rcClient.bottom)); CDC memDC; VERIFY(memDC.CreateCompatibleDC(&dc)); CBitmap* pbmpOld = memDC.SelectObject(&bmp); memDC.FillRect(&(dc.m_ps.rcPaint), &m_brush); CPoint point((rcClient.Width() - m_sizImage.cx) / 2, (rcClient.Height() - m_sizImage.cy) / 2); VERIFY(memDC.DrawState(point, m_sizImage, &m_bitmap, DST_BITMAP | DSS_NORMAL)); VERIFY(dc.BitBlt(0, 0, rcClient.right, rcClient.bottom, &memDC, 0, 0, SRCCOPY)); // VERIFY(memDC.SelectObject(pbmpOld)); // Apparently not needed. } break; case MyMdiClient::dispTile: { CPoint point; for (point.y = 0; point.y < rcClient.Height(); point.y += m_sizImage.cy) { for (point.x = 0; point.x < rcClient.Width(); point.x += m_sizImage.cx) { VERIFY(dc.DrawState(point, m_sizImage, &m_bitmap, DST_BITMAP | DSS_NORMAL)); } } } break; case MyMdiClient::dispStretch: { CBitmap bmp; VERIFY(bmp.CreateCompatibleBitmap(&dc, m_sizImage.cx, m_sizImage.cy)); CDC memDC; VERIFY(memDC.CreateCompatibleDC(&dc)); CBitmap* pbmpOld = memDC.SelectObject(&bmp); ASSERT_VALID(pbmpOld); VERIFY(memDC.DrawState(CPoint(0,0), m_sizImage, &m_bitmap, DST_BITMAP | DSS_NORMAL)); dc.SetStretchBltMode(COLORONCOLOR); VERIFY(dc.StretchBlt(0, 0, rcClient.right, rcClient.bottom, &memDC, 0, 0, m_sizImage.cx, m_sizImage.cy, SRCCOPY)); VERIFY(dc.BitBlt(0, 0, rcClient.right, rcClient.bottom, &dc, 0, 0, SRCCOPY)); } break; } } else { // If no bitmap is selected. dc.FillRect(&(dc.m_ps.rcPaint), &m_brush); } } // BOOL MyMdiClient::OnEraseBkgnd(CDC* /*pDC*/) { VALIDATE; return TRUE; // Return TRUE so background is not erased } // void MyMdiClient::OnSize(UINT nType, int cx, int cy) { VALIDATE; // Force repainting if center mode is selected if (nType != SIZE_MINIMIZED && m_eDisplayMode != MyMdiClient::dispTile) { Invalidate(); } CWnd::OnSize(nType, cx, cy); } // void MyMdiClient::OnDestroy() { VALIDATE; SaveState(); CWnd::OnDestroy(); } // Handle WM_RBUTTONDOWN (by sending to the one place the code is). void MyMdiClient::OnRButtonDown(UINT nFlags, CPoint point) { VALIDATE; OnLButtonDown(nFlags, point); CWnd::OnRButtonDown(nFlags, point); } // Handle WM_LBUTTONDOWN. This is the only place this code exists, for // conciseness. void MyMdiClient::OnLButtonDown(UINT nFlags, CPoint point) { VALIDATE; CMainFrame* pMainFrame = static_cast (AfxGetMainWnd()); ASSERT_VALID(pMainFrame); if (pMainFrame) { DOMYLOG ("Stopping because of WM_LBUTTONDOWN.\n"); pMainFrame->PostMessage(WM_COMMAND, ID_VIEW_STOP_SHOW); } CWnd::OnLButtonDown(nFlags, point); }