Here is what I'm trying to do. I have credits that are scrolling in a certain part of my main window.
I'm running into 1 of 2 issues.
1. If I invalidate hWnd (main window), and it repaints, it causes everything to flicker, and causes some lag.
2. If I only redraw it once, then the area doesn't repaint and it smears the text as it's scrolling.
Objective:
I'm trying to get only a portion of my main window to update not the whole window. I'm not sure how to do this.
I'm assuming I would use RECT like I'm using, but I'm not sure how to only redraw that part of the window properly.
Here is my code.
Main.cpp
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance;
//Main window
hWnd = CreateWindow("mainDialog", "SEAL Reeemiiiiix", WS_POPUP | WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, ((getImageWidth(L"main.png"))+ 5), ((getImageHeight(L"main.png")) + 26), NULL, NULL, hInstance, NULL);
//My scrolling credits
scrollingCredits = CreateWindow("Static", "", WS_CHILDWINDOW | WS_VISIBLE | ES_READONLY | SS_OWNERDRAW, 10, 300, 300, 80, hWnd, (HMENU)IDB_SCROLLINGCREDITS, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
CenterWindow(hWnd);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
static RECT pRect = {10, 300, 260, 380};
switch(message)
{
case WM_DRAWITEM:
{
if(wParam == IDB_SCROLLINGCREDITS)
{
StartScrolling(wParam, lParam);
}
}
break;
case WM_CREATE:
{
//scrollingCredits
SetTimer(hWnd, 1, 100, NULL);
}
break;
case WM_ERASEBKGND:
{
//This minimizes some flickering
return true;
}
break;
case WM_TIMER:
{
InvalidateRect( scrollingCredits, NULL, FALSE );
InvalidateRect( hWnd, &pRect, FALSE );
}
break;
case WM_PAINT:
{
HDC hdcMem;
HGDIOBJ hOld;
HGDIOBJ hbmMem;
static bool painted = false;
hdc = BeginPaint(hWnd, &ps);
// Create an off-screen DC for double-buffering
GetClientRect( scrollingCredits, &pRect );
hdcMem = CreateCompatibleDC(hdc);
hbmMem = CreateCompatibleBitmap(hdc, 300, 80);
hOld = SelectObject(hdcMem, hbmMem);
//drawStuff(hdcMem, L"main.png", 0, 0);
BitBlt(hdc, 10, 300, (getImageWidth(L"main.png")), (getImageHeight(L"main.png")), hdcMem, 10, 300, SRCCOPY);
if(!painted)
{
painted = true;
drawStuff(hdc, L"main.png", 0, 0);
}
//-------------------------------------
//Delete our variables to free memory
//-------------------------------------
SelectObject(hdcMem, hOld);
DeleteObject(hbmMem);
DeleteDC (hdcMem);
EndPaint(hWnd, &ps);
}
break;
default:
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
return 0;
}
Here is the scrolling source code:
//Disable unnecessary warnings
#pragma warning(disable: 4267)
//Our Window variable
HWND scrollingCredits;
char szCredit[][100] =
{
" Property of:",
" ",
"Midwest Palliative and Hospice CareCenter",
"",
" Created By:",
" James"
};
const int nCreditLines = ( sizeof(szCredit) / 100 );
const int nWaitTime = 100;
const int x_dif = 10;
const int y_end = (nCreditLines * (x_dif+1) );
const int y_start = -90;
void RollCredits( HDC dc )
{
static DWORD dwTime = 0;
static int y_mod = y_start;
if( dwTime <= GetTickCount() )
{
y_mod++;
dwTime = (GetTickCount()+100);
}
if( y_mod == y_end)
{
y_mod = y_start;
dwTime = (GetTickCount()+nWaitTime);
}
for( int i = 0; i < nCreditLines; i++)
{
int y = ((i * x_dif)) - y_mod;
TextOut( dc , 0 ,y , szCredit[i], strlen(szCredit[i]) );
}
}
void StartScrolling(WPARAM wParam, LPARAM lParam)
{
LPDRAWITEMSTRUCT pDrawItem = (LPDRAWITEMSTRUCT)lParam;
if( wParam == IDB_SCROLLINGCREDITS )
{
static HFONT hFont = 0;
if( hFont == 0 )
{
if( (hFont = CreateFont( 9,0,0,0,400,0,0,0, OEM_CHARSET,0,0,0,DEFAULT_PITCH | FF_SCRIPT,"terminal")) == 0 )
{
MessageBox( 0, "Failed to create font!\n", "Errr", 0 );
PostQuitMessage(0);
}
}
SelectObject( pDrawItem->hDC, hFont );
SetBkMode( pDrawItem->hDC, TRANSPARENT);
RollCredits( pDrawItem->hDC );
}
}
Also here is my window rendering code (although I don't think this is relevant)
void drawStuff(HDC hdc, const WCHAR *image, int x, int y)
{
Graphics gr(hdc);
Image *img = new Image(image, false);
gr.DrawImage(img, x, y, img->GetWidth(), img->GetHeight());
delete img;
}
The smearing I am referring to is in the attachment.
Any assistance is appreciated.