1 //////////////////////////////////////////////
\r
3 // Definitions for the CView class
\r
7 #include "resource.h"
\r
10 CView::CView() : m_xCurrentScroll(0), m_yCurrentScroll(0)
\r
18 BOOL CView::FileOpen(LPCTSTR szFilename)
\r
22 m_bmImage.LoadImage(szFilename, 0, 0, LR_LOADFROMFILE);
\r
25 m_bmImage.DeleteObject();
\r
27 return (BOOL)m_bmImage.GetHandle();
\r
30 BOOL CView::FileSave(LPCTSTR pszFile)
\r
33 BOOL bResult = FALSE;
\r
34 if (File.Open(pszFile, OPEN_ALWAYS))
\r
36 // Create our LPBITMAPINFO object
\r
37 CBitmapInfoPtr pbmi(&m_bmImage);
\r
39 // Create the reference DC for GetDIBits to use
\r
42 // Use GetDIBits to create a DIB from our DDB, and extract the colour data
\r
43 MemDC.GetDIBits(&m_bmImage, 0, pbmi->bmiHeader.biHeight, NULL, pbmi, DIB_RGB_COLORS);
\r
44 std::vector<byte> vBits(pbmi->bmiHeader.biSizeImage, 0);
\r
45 byte* lpvBits = &vBits.front();
\r
47 MemDC.GetDIBits(&m_bmImage, 0, pbmi->bmiHeader.biHeight, lpvBits, pbmi, DIB_RGB_COLORS);
\r
49 LPBITMAPINFOHEADER pbmih = &pbmi->bmiHeader;
\r
50 BITMAPFILEHEADER hdr = {0};
\r
51 hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"
\r
52 hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbmih->biSize + pbmih->biClrUsed * sizeof(RGBQUAD) + pbmih->biSizeImage);
\r
53 hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbmih->biSize + pbmih->biClrUsed * sizeof (RGBQUAD);
\r
55 File.Write((LPCVOID) &hdr, sizeof(BITMAPFILEHEADER));
\r
56 File.Write((LPCVOID) pbmih, sizeof(BITMAPINFOHEADER) + pbmih->biClrUsed * sizeof (RGBQUAD));
\r
57 File.Write((LPCVOID) lpvBits, (int) pbmih->biSizeImage);
\r
59 if (File.GetLength() == sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + pbmih->biClrUsed * sizeof (RGBQUAD) + (int) pbmih->biSizeImage)
\r
66 CRect CView::GetImageRect()
\r
69 ::GetObject(m_bmImage, sizeof(BITMAP), &bm);
\r
72 rc.right = bm.bmWidth;
\r
73 rc.bottom = bm.bmHeight;
\r
78 void CView::OnDraw(CDC* pDC)
\r
80 if (m_bmImage.GetHandle())
\r
82 // We have an image, so display it
\r
84 CRect rcView = GetClientRect();
\r
85 CBitmap* pOldBitmap = memDC.SelectObject(&m_bmImage);
\r
86 pDC->BitBlt(0, 0, rcView.Width(), rcView.Height(), &memDC, m_xCurrentScroll, m_yCurrentScroll, SRCCOPY);
\r
87 memDC.SelectObject(pOldBitmap);
\r
91 // There is no image, so display a hint to get one
\r
92 CRect rc = GetClientRect();
\r
93 pDC->DrawText(_T("Use the Menu or ToolBar to open a Bitmap File"), -1, rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
\r
97 void CView::OnInitialUpdate()
\r
99 // OnInitialUpdate is called immediately after the window is created
\r
100 TRACE(_T("View window created\n"));
\r
102 ShowScrollBar(SB_BOTH, FALSE);
\r
105 void CView::OnHScroll(WPARAM wParam, LPARAM lParam)
\r
107 UNREFERENCED_PARAMETER(lParam);
\r
110 switch (LOWORD(wParam))
\r
112 case SB_PAGEUP: // User clicked the scroll bar shaft left of the scroll box.
\r
113 xNewPos = m_xCurrentScroll - 50;
\r
116 case SB_PAGEDOWN: // User clicked the scroll bar shaft right of the scroll box.
\r
117 xNewPos = m_xCurrentScroll + 50;
\r
120 case SB_LINEUP: // User clicked the left arrow.
\r
121 xNewPos = m_xCurrentScroll - 5;
\r
124 case SB_LINEDOWN: // User clicked the right arrow.
\r
125 xNewPos = m_xCurrentScroll + 5;
\r
128 case SB_THUMBPOSITION: // User dragged the scroll box.
\r
129 xNewPos = HIWORD(wParam);
\r
132 case SB_THUMBTRACK: // User dragging the scroll box.
\r
133 xNewPos = HIWORD(wParam);
\r
137 xNewPos = m_xCurrentScroll;
\r
140 // Scroll the window.
\r
141 xNewPos = MAX(0, xNewPos);
\r
142 xNewPos = MIN( xNewPos, GetImageRect().Width() - GetClientRect().Width() );
\r
143 int xDelta = xNewPos - m_xCurrentScroll;
\r
144 m_xCurrentScroll = xNewPos;
\r
145 ScrollWindowEx(-xDelta, 0, NULL, NULL, NULL, NULL, SW_INVALIDATE);
\r
147 // Reset the scroll bar.
\r
148 SCROLLINFO si = {0};
\r
149 si.cbSize = sizeof(si);
\r
150 si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
\r
151 si.cbSize = sizeof(si);
\r
152 si.fMask = SIF_POS;
\r
153 si.nPos = m_xCurrentScroll;
\r
154 SetScrollInfo(SB_HORZ, si, TRUE);
\r
157 void CView::OnVScroll(WPARAM wParam, LPARAM lParam)
\r
159 UNREFERENCED_PARAMETER(lParam);
\r
162 switch (LOWORD(wParam))
\r
164 case SB_PAGEUP: // User clicked the scroll bar shaft above the scroll box.
\r
165 yNewPos = m_yCurrentScroll - 50;
\r
168 case SB_PAGEDOWN: // User clicked the scroll bar shaft below the scroll box.
\r
169 yNewPos = m_yCurrentScroll + 50;
\r
172 case SB_LINEUP: // User clicked the top arrow.
\r
173 yNewPos = m_yCurrentScroll - 5;
\r
176 case SB_LINEDOWN: // User clicked the bottom arrow.
\r
177 yNewPos = m_yCurrentScroll + 5;
\r
180 case SB_THUMBPOSITION: // User dragged the scroll box.
\r
181 yNewPos = HIWORD(wParam);
\r
184 case SB_THUMBTRACK: // User dragging the scroll box.
\r
185 yNewPos = HIWORD(wParam);
\r
189 yNewPos = m_yCurrentScroll;
\r
192 // Scroll the window.
\r
193 yNewPos = MAX(0, yNewPos);
\r
194 yNewPos = MIN( yNewPos, GetImageRect().Height() - GetClientRect().Height() );
\r
195 int yDelta = yNewPos - m_yCurrentScroll;
\r
196 m_yCurrentScroll = yNewPos;
\r
197 ScrollWindowEx(0, -yDelta, NULL, NULL, NULL, NULL, SW_INVALIDATE);
\r
199 // Reset the scroll bar.
\r
200 SCROLLINFO si = {0};
\r
201 si.cbSize = sizeof(si);
\r
202 si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
\r
203 si.cbSize = sizeof(si);
\r
204 si.fMask = SIF_POS;
\r
205 si.nPos = m_yCurrentScroll;
\r
206 SetScrollInfo(SB_VERT, si, TRUE);
\r
209 void CView::OnWindowPosChanged(WPARAM wParam, LPARAM lParam)
\r
211 UNREFERENCED_PARAMETER(wParam);
\r
212 UNREFERENCED_PARAMETER(lParam);
\r
214 if (m_bmImage.GetHandle())
\r
216 CRect rcImage = GetImageRect();
\r
217 DWORD dwStyle = (DWORD)GetWindowLongPtr(GWL_STYLE);
\r
218 DWORD dwExStyle = (DWORD)GetWindowLongPtr(GWL_EXSTYLE);
\r
219 AdjustWindowRectEx(&rcImage, dwStyle, FALSE, dwExStyle);
\r
221 CRect rcView = GetClientRect();
\r
222 AdjustWindowRectEx(&rcView, dwStyle, FALSE, dwExStyle);
\r
224 SCROLLINFO si = {0};
\r
225 si.cbSize = sizeof(si);
\r
226 si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
\r
229 if (rcView.Width() >= rcImage.Width())
\r
231 m_xCurrentScroll = 0;
\r
232 ShowScrollBar(SB_HORZ, FALSE);
\r
236 si.nMax = rcImage.Width();
\r
237 si.nPage = rcView.Width();
\r
238 si.nPos = m_xCurrentScroll;
\r
239 SetScrollInfo(SB_HORZ, si, TRUE);
\r
240 ShowScrollBar(SB_HORZ, TRUE);
\r
243 if (rcView.Height() >= rcImage.Height())
\r
245 m_yCurrentScroll = 0;
\r
246 ShowScrollBar(SB_VERT, FALSE);
\r
250 si.nMax = rcImage.Height();
\r
251 si.nPage = rcView.Height();
\r
252 si.nPos = m_yCurrentScroll;
\r
253 SetScrollInfo(SB_VERT, si, TRUE);
\r
254 ShowScrollBar(SB_VERT, TRUE);
\r
257 int xNewPos = MIN(m_xCurrentScroll, rcImage.Width() - rcView.Width());
\r
258 xNewPos = MAX(xNewPos, 0);
\r
259 int xDelta = xNewPos - m_xCurrentScroll;
\r
261 int yNewPos = MIN(m_yCurrentScroll, rcImage.Height() - rcView.Height());
\r
262 yNewPos = MAX(yNewPos, 0);
\r
263 int yDelta = yNewPos - m_yCurrentScroll;
\r
265 ScrollWindowEx(-xDelta, -yDelta, NULL, NULL, NULL, NULL, SW_INVALIDATE);
\r
266 m_xCurrentScroll = xNewPos;
\r
267 m_yCurrentScroll = yNewPos;
\r
270 Invalidate(); // Keep the text centered in the window
\r
273 void CView::PreCreate(CREATESTRUCT &cs)
\r
275 // Set the Window Class name
\r
276 cs.lpszClass = _T("View");
\r
278 cs.style = WS_CHILD | WS_HSCROLL | WS_VSCROLL ;
\r
280 // Set the extended style
\r
281 cs.dwExStyle = WS_EX_CLIENTEDGE;
\r
284 LRESULT CView::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
288 case WM_WINDOWPOSCHANGED:
\r
289 OnWindowPosChanged(wParam, lParam);
\r
293 OnHScroll(wParam, lParam);
\r
297 OnVScroll(wParam, lParam);
\r
301 // Pass unhandled messages on for default processing
\r
302 return WndProcDefault(uMsg, wParam, lParam);
\r