@@ -16,16 +16,11 @@ CCanvasWindow::CCanvasWindow()
1616 , m_hitCanvasSizeBox(HIT_NONE)
1717 , m_ptOrig { -1 , -1 }
1818{
19- m_ahbmCached[0 ] = m_ahbmCached[1 ] = NULL ;
2019 m_rcResizing.SetRectEmpty ();
2120}
2221
2322CCanvasWindow::~CCanvasWindow ()
2423{
25- if (m_ahbmCached[0 ])
26- ::DeleteObject (m_ahbmCached[0 ]);
27- if (m_ahbmCached[1 ])
28- ::DeleteObject (m_ahbmCached[1 ]);
2924}
3025
3126RECT CCanvasWindow::GetBaseRect ()
@@ -119,16 +114,30 @@ VOID CCanvasWindow::zoomTo(INT newZoom, LONG left, LONG top)
119114 Invalidate (TRUE );
120115}
121116
122- VOID CCanvasWindow::DoDraw (HDC hDC, RECT& rcClient, RECT& rcPaint)
117+ BOOL CCanvasWindow::DoDraw (HDC hDC, RECT& rcClient, RECT& rcPaint)
123118{
124119 // This is the target area we have to draw on
125120 CRect rcCanvasDraw;
126121 rcCanvasDraw.IntersectRect (&rcClient, &rcPaint);
127122
123+ // Calculate image size
124+ CRect rcImage;
125+ GetImageRect (rcImage);
126+ SIZE sizeImage = { imageModel.GetWidth (), imageModel.GetHeight () };
127+
128128 // We use a memory bitmap to reduce flickering
129+ HBITMAP hbmCache1 = CreateDIBWithProperties (rcClient.right , rcClient.bottom );
130+ if (!hbmCache1)
131+ return FALSE ; // Out of memory
132+ HBITMAP hbmCache2 = CreateDIBWithProperties (sizeImage.cx , sizeImage.cy );
133+ if (!hbmCache2)
134+ {
135+ ::DeleteObject (hbmCache1);
136+ return FALSE ; // Out of memory
137+ }
138+
129139 HDC hdcMem0 = ::CreateCompatibleDC (hDC);
130- m_ahbmCached[0 ] = CachedBufferDIB (m_ahbmCached[0 ], rcClient.right , rcClient.bottom );
131- HGDIOBJ hbm0Old = ::SelectObject (hdcMem0, m_ahbmCached[0 ]);
140+ HGDIOBJ hbm0Old = ::SelectObject (hdcMem0, hbmCache1);
132141
133142 // Fill the background on hdcMem0
134143 ::FillRect (hdcMem0, &rcCanvasDraw, (HBRUSH)(COLOR_APPWORKSPACE + 1 ));
@@ -138,11 +147,6 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint)
138147 if (!selectionModel.m_bShow && !::IsWindowVisible (textEditWindow))
139148 drawSizeBoxes (hdcMem0, &rcBase, FALSE , &rcCanvasDraw);
140149
141- // Calculate image size
142- CRect rcImage;
143- GetImageRect (rcImage);
144- SIZE sizeImage = { imageModel.GetWidth (), imageModel.GetHeight () };
145-
146150 // Calculate the target area on the image
147151 CRect rcImageDraw = rcCanvasDraw;
148152 CanvasToImage (rcImageDraw);
@@ -154,8 +158,7 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint)
154158
155159 // hdcMem1 <-- imageModel
156160 HDC hdcMem1 = ::CreateCompatibleDC (hDC);
157- m_ahbmCached[1 ] = CachedBufferDIB (m_ahbmCached[1 ], sizeImage.cx , sizeImage.cy );
158- HGDIOBJ hbm1Old = ::SelectObject (hdcMem1, m_ahbmCached[1 ]);
161+ HGDIOBJ hbm1Old = ::SelectObject (hdcMem1, hbmCache2);
159162 ::BitBlt (hdcMem1, rcImageDraw.left, rcImageDraw.top, rcImageDraw.Width(), rcImageDraw.Height(),
160163 imageModel.GetDC(), rcImageDraw.left, rcImageDraw.top, SRCCOPY);
161164
@@ -208,6 +211,10 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint)
208211 // Clean up hdcMem0
209212 ::SelectObject (hdcMem0, hbm0Old);
210213 ::DeleteDC (hdcMem0);
214+ ::DeleteObject (hbmCache2);
215+ ::DeleteObject (hbmCache1);
216+
217+ return TRUE ;
211218}
212219
213220VOID CCanvasWindow::updateScrollRange ()
@@ -691,9 +698,22 @@ LRESULT CCanvasWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
691698 RECT rcClient;
692699 GetClientRect (&rcClient);
693700
701+ static BOOL s_bShowedOutOfMemory = FALSE ; // Don't show "Out Of Memory" message multiple time
702+
694703 PAINTSTRUCT ps;
695704 HDC hDC = BeginPaint (&ps);
696- DoDraw (hDC, rcClient, ps.rcPaint );
705+
706+ if (DoDraw (hDC, rcClient, ps.rcPaint ))
707+ {
708+ s_bShowedOutOfMemory = FALSE ;
709+ }
710+ else if (!s_bShowedOutOfMemory)
711+ {
712+ ShowOutOfMemory ();
713+ s_bShowedOutOfMemory = TRUE ;
714+ imageModel.ClearHistory (); // Reduce memory usage
715+ }
716+
697717 EndPaint (&ps);
698718 return 0 ;
699719}
0 commit comments