For some time now I have been trying to resolve the WM_PAINT code or my application. Every advise I have ever been given on this issue, I have applied.
Someone said I should carry out all the DC operations in WM_PAINT. I did that.
Someone said I should display output calculatedly. I have already tried a trillion o different calculations.
Although my apps documents consist of one or more several pages, each page consists of different graphics that are rendered arbitrarily.
When I render directly to the window dc, the display is usually perfect except for flickering during scrolling.
In order to solve the flickering problem, I decided to use double line buffering which works well only on the first page, after which display goes haywire.
The relevant codes are shown below:
case WM_CREATE:
SetAppScrollInfo(hWnd, iPageWidth, iPageHeight);
HDC hDC = GetDC(hWnd);
tuple Tuple = GetAppDocumentSize(hWnd, hDC, iPageWidth, iPageHeight, eResultActionType);
hMemDC = CreateCompatibleDC(hDC);
iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
iScreenHeight = GetSystemMetrics(SM_CYSCREEN);
hBitmap = CreateCompatibleBitmap(hDC, iScreenWidth, iScreenHeight);
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
PrepareMemDC(hMemDC);
RECT rc;
rc.left = 0;
rc.top = 0;
rc.right = iScreenWidth;
rc.bottom = iScreenHeight;
HBRUSH hBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
FillRect(hMemDC, &rc, hBrush);
ReleaseDC(hWnd, hDC);
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
tuple Tuple = GetAppDocumentSize(hWnd, hdc, iPageWidth, iPageHeight, eResultActionType);
double dOneMMX = get<0>(Tuple);
double dOneMMY = get<1>(Tuple);
int iOffsetX = get<2>(Tuple);
int iOffsetY = get<3>(Tuple);
int iHPos = get<4>(Tuple);
int iVPos = get<5>(Tuple);
PrepareMemDC(hMemDC, iHPos, iVPos);
WriteForWindowDC(hWnd, hMemDC, vClassResult, classResult, dOneMMX, dOneMMY, iOffsetX, iOffsetY, iOffsetX, iOffsetY, iPageWidth, iPageHeight, iResultTerm, eWriteType, eResultActionType, eBroadSheetActionType, eBroadSheetType, eResultsType, eResultSheetActionType);
EndPaint(hWnd, &ps);
}
void PrepareMemDC(HDC hDC, int iScrollPosX, int iScrollPosY)
{
int iWindowExtX = static_cast<int>(GetDeviceCaps(hDC, HORZSIZE));
int iWindowExtY = static_cast<int>(GetDeviceCaps(hDC, VERTSIZE));
int iViewPortX = static_cast<int>(0.3 * GetDeviceCaps(hDC, HORZRES));
int iViewPortY = static_cast<int>(0.3 * GetDeviceCaps(hDC, VERTRES));
SetMapMode(hDC, MM_ISOTROPIC);
SetWindowExtEx(hDC, iWindowExtX, iWindowExtY, nullptr);
SetViewportExtEx(hDC, iViewPortX, iViewPortY, nullptr);
SetWindowOrgEx(hDC, iScrollPosX, iScrollPosY, nullptr);
}
void WriteForWindowDC(HWND hWnd, HDC hMemDC, vector<ClassResult>& vClassResult, ClassResult& classResult, double dOneMMX, double dOneMMY, int iLeft, int iTop, int iOffsetX, int iOffsetY, int iPageWidth, int iPageHeight, int iTerm, WriteType eWriteType, ResultActionType eResultActionType, BroadSheetActionType eBroadSheetActionType, BroadSheetTypes eBroadSheetType, ResultsType eResultsType, ResultSheetActionType eResultSheetActionType)
{
RECT rcFillRect;
HBRUSH hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
if (eResultActionType == ResultActionType::RAT_VIEW_BROADSHEET)
{
if (vClassResult.size())
{
for (int iPage = 0; iPage < static_cast<int>(vClassResult.size()); iPage++)
{
int iPageTop = iTop + iPage * (iPageHeight + iOffsetY);
classResult = vClassResult[iPage];
rcFillRect.left = iLeft;
rcFillRect.top = iPageTop;
rcFillRect.right = rcFillRect.left + iPageWidth;
rcFillRect.bottom = rcFillRect.top + iPageHeight;
FillRect(hMemDC, &rcFillRect, hBrush);
WriteBroadSheet(hWnd, hMemDC, dOneMMX, dOneMMY, iLeft, iPageTop, iOffsetX, iOffsetY, iPageWidth, iPageHeight, iTerm, eWriteType, eResultActionType, eBroadSheetActionType, eBroadSheetType, classResult);
}
}
}
}
void SetAppScrollInfo(HWND hWnd, int iPageWidth, int iPageHeight, int iOffsetX, int iOffsetY, int iNumPages,int iPosX, int iPosY)
{
RECT rc;
GetClientRect(hWnd, &rc);
SCROLLINFO scrollInfo;
scrollInfo.cbSize = sizeof(SCROLLINFO);
scrollInfo.fMask = scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
scrollInfo.nPos = iPosX;
scrollInfo.nMin = 0;
scrollInfo.nMax = std::max(iPageWidth + 2 * iOffsetX, (int)rc.right);
scrollInfo.nPage = std::max(iPageWidth + 2 * iOffsetX, (int)rc.right);
SetScrollInfo(hWnd, SB_HORZ, &scrollInfo, TRUE);
scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
scrollInfo.nPos = iPosY;
scrollInfo.nMin = 0;
scrollInfo.nMax = std::max(iNumPages * (iPageHeight + iOffsetY), (int)rc.bottom);
scrollInfo.nPage = std::max(iPageHeight + iOffsetY, (int)rc.bottom);
SetScrollInfo(hWnd, SB_VERT, &scrollInfo, TRUE);
}
case WM_VSCROLL:
{
SCROLLINFO scrollInfo;
scrollInfo.fMask = SIF_ALL;
GetScrollInfo(hWnd, SB_VERT, &scrollInfo);
int yScrollPos = scrollInfo.nPos;
int iPosition = HIWORD(wParam);
switch (LOWORD(wParam))
{
case SB_TOP:
yScrollPos = 0;
break;
case SB_BOTTOM:
yScrollPos = scrollInfo.nMax - scrollInfo.nPage + 1;
break;
case SB_LINEUP:
yScrollPos -= LINE_HEIGHT;
break;
case SB_LINEDOWN:
yScrollPos += LINE_HEIGHT;
break;
case SB_PAGEUP:
yScrollPos -= scrollInfo.nPage;
break;
case SB_PAGEDOWN:
yScrollPos += scrollInfo.nPage;
break;
case SB_THUMBPOSITION:
yScrollPos = scrollInfo.nTrackPos;
break;
case SB_THUMBTRACK:
yScrollPos = iPosition;
break;
}
yScrollPos = max(yScrollPos, 0);
yScrollPos = min(yScrollPos, static_cast<int>(scrollInfo.nMax) - static_cast<int>(scrollInfo.nPage) + 1);
if (yScrollPos != scrollInfo.nPos)
{
SIZE szDistance(0, scrollInfo.nPos - yScrollPos);
scrollInfo.fMask = SIF_POS;
scrollInfo.nPos = yScrollPos;
SetScrollInfo(hWnd, SB_VERT, &scrollInfo, TRUE);
ScrollWindow(hWnd, 0, szDistance.cy, nullptr, nullptr);
UpdateWindow(hWnd);
}
}
break;
case WM_HSCROLL:
{
SCROLLINFO scrollInfo;
scrollInfo.fMask = SIF_ALL;
GetScrollInfo(hWnd, SB_HORZ, &scrollInfo);
int xScrollPos = scrollInfo.nPos;
int iPosition = HIWORD(wParam);
switch (LOWORD(wParam))
{
case SB_LEFT:
xScrollPos = 0;
break;
case SB_RIGHT:
xScrollPos = scrollInfo.nMax + 1;
break;
case SB_LINELEFT:
xScrollPos -= LINE_WIDTH;
break;
case SB_LINERIGHT:
xScrollPos += LINE_WIDTH;
break;
case SB_PAGELEFT:
xScrollPos -= scrollInfo.nPage;
break;
case SB_PAGERIGHT:
xScrollPos += scrollInfo.nPage;
break;
case SB_THUMBPOSITION:
xScrollPos = scrollInfo.nTrackPos;
break;
case SB_THUMBTRACK:
xScrollPos = iPosition;
break;
}
xScrollPos = max(xScrollPos, 0);
xScrollPos = min(xScrollPos, static_cast<int>(scrollInfo.nMax) - static_cast<int>(scrollInfo.nPage) + 1);
if (xScrollPos != scrollInfo.nPos)
{
SIZE szDistance(scrollInfo.nPos - xScrollPos, 0);
scrollInfo.fMask = SIF_POS;
scrollInfo.nPos = xScrollPos;
SetScrollInfo(hWnd, SB_HORZ, &scrollInfo, TRUE);
ScrollWindow(hWnd, szDistance.cx, 0, nullptr, nullptr);
UpdateWindow(hWnd);
}
}
std::tuple<double,double,int,int,int,int> GetAppDocumentSize(HWND hWnd, HDC hDC, int& iWidth, int& iHeight, ResultActionType eResultActionType)
{
int iWindowExtX = static_cast<int>(GetDeviceCaps(hDC,HORZSIZE));
int iWindowExtY = static_cast<int>(GetDeviceCaps(hDC, VERTSIZE));
int iViewPortX = static_cast<int>(0.3 * GetDeviceCaps(hDC, HORZRES));
int iViewPortY = static_cast<int>(0.3 * GetDeviceCaps(hDC, VERTRES));
SetMapMode(hDC, MM_ISOTROPIC);
SetWindowExtEx(hDC, iWindowExtX, iWindowExtY, nullptr);
SetViewportExtEx(hDC, iViewPortX, iViewPortY, nullptr);
int iDeviceSizePixelsX = GetDeviceCaps(hDC, HORZRES);
int iDeviceSizePixelsY = GetDeviceCaps(hDC, VERTRES);
int iDeviceSizeMMX = GetDeviceCaps(hDC, HORZSIZE);
int iDeviceSizeMMY = GetDeviceCaps(hDC, VERTSIZE);
double dOneMMX = (double)iDeviceSizePixelsX/ (double)iDeviceSizeMMX;
double dOneMMY = (double)iDeviceSizePixelsY/ (double)iDeviceSizeMMY;
if (eResultActionType == ResultActionType::RAT_VIEW_RESULTSHEET)
{
iWidth = static_cast<int>(dOneMMX * 210);
iHeight = static_cast<int>(dOneMMY * 297);
}
else
{
iHeight = static_cast<int>(dOneMMX * 210);
iWidth = static_cast<int>(dOneMMY * 297);
}
int iOffsetX = (int)Approximate(10 * dOneMMX,0);
int iOffsetY = (int)Approximate(10 * dOneMMY,0);
SCROLLINFO scrollInfo;
scrollInfo.cbSize = sizeof(SCROLLINFO);
scrollInfo.fMask = SIF_POS;
GetScrollInfo(hWnd,SB_HORZ, &scrollInfo);
int xOrg = scrollInfo.nPos;
scrollInfo.fMask = SIF_POS;
GetScrollInfo(hWnd,SB_VERT, &scrollInfo);
int yOrg = scrollInfo.nPos;
SetWindowOrgEx(hDC,xOrg, yOrg,nullptr);
return std::tuple(dOneMMX, dOneMMY, iOffsetX, iOffsetY,xOrg,yOrg);
}
What I have tried:
I have been debugging and googling for a reasonably long period now.