Click to See Complete Forum and Search --> : It's annoying:got a problem with WM_PAINT and UpdateWindow, and


me-$-on
January 17th, 2008, 03:40 AM
until now no one knew the answer.
Hello, I have a Problem with the WM_PAINT in connenction with the UpdateWindow(or RedrawWindow) and a Region, which shall be invalidated.
The idea behind that is to build a own mouseover for later implementation in an own hoverbtn class.
As i enter the region with my mouse, the global brush color will be changed, the region invalidated and the window updated, what causes a WM_PAINT and the entered region changes its color.
If the region is left, the same things happens, setting the brush color back to initialization,, Update Window what causes another WM_PAINT and the button ( region)is white again.
The problem ( iv'e tried it on my laptop and on my pc, since it seems as if ist is memoryamount-depended )is, that after 170 scrolls ( on 1GB ram) there happens nothing more.
I suppose I have to clear up the message queue, but I'm not sure about that.
The programm freezes, and does nothing:
Here are the important code-snippets:
-

case WM_PAINT:
{
// blitting the attached skin to the hektagon region -------------------
RECT wnd6;
GetWindowRect(mwinhan,&wnd6);
HDC hdc;
PAINTSTRUCT pskn;

hdc = BeginPaint(mwinhan,&pskn);
BitBlt(pskn.hdc,0,0,200,200,dcskin,-10,-5,SRCCOPY);
// end: blitting skin-----------------------------------------------------
//
//creating default button for config with caption ---------------------
SelectObject(hdc,(HBRUSH)CreateSolidBrush((COLORREF)btnbg)) ;
Polygon(hdc,bpt,3);
SetBkMode(hdc,TRANSPARENT);
TextOut(hdc,(bb.x/2)+3,ab.y+2,"Config", 6);
EndPaint(mwinhan, &pskn);

//end: button with caption---------------------------------------------
// not optimized, but it works-----------------------------------------
//hoverrect r1(50,70,40,40,120,200); // trial with class
break;
}
//------------------------------------------------------------------------------------------

-

//------------------------------------------------------------------------------------------
case WM_MOUSEMOVE:
{
// getting mousecoordinates while moving--------------------------------
psxy.x = LONG(LOWORD(wm_Lflags));
psxy.y = LONG(HIWORD(wm_Lflags));
// END: getting mousecoordinates----------------------------------------
//
// hovering not optimized, it flickers
// a redraw is not neccessary, if the mouse is not in a region
// but moves inside the hektagon. This must be implemented.
// idea: InvalidateRegion........UpdateRegion, or a switch for
// binary comparison or a Mousetrace
//-------------------------the trial-------------------------------------------
//-------------------------the trial-------------------------------------------

if((PtInRegion(h3rgn,psxy.x, psxy.y) != 0) && (pin == false))
{
pin = true;
btnbg = (RGB(125,125,125));
InvalidateRgn(mwinhan,h3rgn,false);
//UpdateWindow(mwinhan);
RedrawWindow(mwinhan,NULL,h3rgn,RDW_INTERNALPAINT);
}
if((PtInRegion(h3rgn,psxy.x, psxy.y) == 0) && (pin == true ))
{
pin = false;
btnbg = (RGB(255,255,255));
InvalidateRgn(mwinhan,h3rgn,false);
//UpdateWindow(mwinhan);
RedrawWindow(mwinhan,NULL,h3rgn,RDW_INTERNALPAINT);
}
//----------not optimized: use a locale-------------------------------------
break;

-
-
-
So, what could cause this freezing if not an overfilled message queue?
-
Does anyone know such behaviour?

olivthill
January 17th, 2008, 06:19 AM
The brush has to be deleted. Save the old brush and add a DeleteObject, e.g.:
case WM_PAINT:
{
// blitting the attached skin to the hektagon region -------------------
RECT wnd6;
GetWindowRect(mwinhan,&wnd6);
HDC hdc;
PAINTSTRUCT pskn;
HBRUSH hbr;

hdc = BeginPaint(mwinhan,&pskn);
BitBlt(pskn.hdc,0,0,200,200,dcskin,-10,-5,SRCCOPY);
// end: blitting skin-----------------------------------------------------
//
//creating default button for config with caption ---------------------
hbr = SelectObject(hdc,(HBRUSH)CreateSolidBrush((COLORREF)btnbg)) ;
Polygon(hdc,bpt,3);
SetBkMode(hdc,TRANSPARENT);
TextOut(hdc,(bb.x/2)+3,ab.y+2,"Config", 6);
DeleteObject(SelectObject(hdc, hbr));
EndPaint(mwinhan, &pskn);

me-$-on
January 17th, 2008, 07:02 AM
SHIIAT!
How stupid could i have been?
Memory-filling while creating thousands of brush-objects.
Thanks.
Perhaps this can excuse it:
In Germany we have (unless You are no German) a proverb:
" Ich seh den Wald vor lauter Bäumen nicht ."
What means:

"I can't see the forest because of all the trees."

-
I think , that was my fault.
Thank You very much!!
See Ya!
.-----------------------
-----------------------
I'm back!
Your hint was right, but not the solution.
This problem still appears.
I'll use MS-VC to debug.
We will see......

MaxPower
January 18th, 2008, 01:58 PM
Aren't you supposed to "return 0;" when you handle a message,
not "break;" ? Could that be the problem?

me-$-on
January 21st, 2008, 04:39 AM
I already changed that ,too, for testing it in that way.NOTHING.
Its strange, no one can solve this,
What i think, is that DispatchMessage should remove incoming Messages from the queue, would be strange, if I would have to call for that again, while already using a DispatchMessage...
HELP!

srelu
January 21st, 2008, 06:26 AM
Debugging:
If you suspect your window receives an unreasonably high amount of messages, when the application starts, create and open a file. In the window procedure, before the switch(msg) line, place a WriteFile to write each message and it's parameters in the file. After the application ends, you can inspect that file.

Alternatively, you can use Spy for the same purpose.

srelu
January 21st, 2008, 11:05 PM
I made a project and ran your code.
There were lots of undefined variables, I supplied values for each of them to my best ability until I had it up and runnig.
I failed to obtain the error you talked about. I moved the cursor in and out the region till I get tired and bored (4-5 minutes). Nothing bad happened, the region toggled accurately between gry and white colors till the end.

Put it simply, the error doesn't seem to be in the code you posted.

Maybe I didn't understand exactly your intentions, I cannot find any relation between between the control you paint and the image you display using BitBlt.
Anyway there is an error in the BitBlt, you specify the coordinates in the source DC as being -10 and -5. That's a memory DC, by specifing coordinates outside the bitmap, you in fact ask BitBlt to acces a memory area that doesn't belong to the bitmap. Where the DC stored the bitmap in the memory nobody knows (except Microsoft), but atempts to access memory areas not supposed to be accessed (even only for read) may lead to unpleasant surprises.
For the case of the error you complained about, I don't think it's caused by this issue. But it may be the tip of the iceberg. I'm intrigued how did you handle the bitmap and the DC to make that "offset" necessary (you didn't post that part of your code).

What may be different between the code I tested and your code may be the DC I talked about. Another difference can be h3rgn. (Don't forget that an HRGN object it's a GDI object that needs to be created and deleted like any other GDI object.)
Do you have any code in the begining of the WndProc before the switch(msg) statement ?
Do you have break or return statements at the end of each case ?

What else may be in your application only you know. I suggest you to post a simplified but fully functional version, with everything necessary to generate the error.

me-$-on
January 22nd, 2008, 05:53 AM
Thank You very much.
Looked long for answers like that.
I'll post the desired parts of the code this evening.
Until now i want to say, that I used the flipcode.com tutorial for blitting bmps to an window, and giving the window another shape , also for erasing grabbing and the titlebar.
It shall be a window, looking a bit like a panel.
It sounds very strange, that You did not have this error.
If You would like to be patient enough, so this evening i will post the entire WinMain and WndProc ( which is filled up with breaks at the end of each switch case, and it's first case is the WM_CREATE ....... what I haven't done, is treating the h3rgn as a GDI object... means, i think, i was never deleting it, after creating........ will surely be painted all time.
Perhaps that could have been the cause for memory-overflow.
-
Which variables aren't initialized?
-
Till evening.....

srelu
January 22nd, 2008, 11:47 PM
Which variables aren't initialized?Undeclared or uninitialized variables:
- mwinhan (supposed to be the hanlde of the window)
- dcskin (supposed to be a memory context device - no info about the bitmap selected in it)
- btnbg (supposed to be a COLORREF)
- bpt (supposed to be a pointer to an array of POINTs)
- ab, bb (supposed to be POINTs)
- wm_Lflags (supposed to be LPARAM)
- psxy (supposed to be POINT)
- pin (supposed to be BOOL)
- h3rgn (supposed to be HRGN created with the bpt array)

me-$-on
January 23rd, 2008, 07:15 AM
Hello again!
Forgot posting yesterday, i was too tired, sept from 18.00 till 6.00.
But now I will do it.
Then You can see, that those variables can't be unitialized.
They are, during processing.
You will have the WinMain and the WndProc now here, starting with main.cpp.
( I figured out, that using a global static h3rgn variable solves the problem, i think in this code there isn't the solution, it is another state of work.
But youre welcome:


qlp_main.cpp



// Q L P

// The "quick launch panel."
// What is it?
// The quicklaunch panel is a windows application aimed to replace or
// support the taskbar's quicklaunch function.
// It is specially written for mice with adjustable extra buttons, to
// make quicklaunch possible, without having to move the mouse to
// where the taskbar is, but from wherever the extrabutton was pressed
// If someone prefers, he / she can link qlp to the extra button and join qlp,
// what results in a hexagon popping up on the screen offering to start
// personal chosen quicklaunch applications , adding new or deleting
// the existent ones.
// So far. For more details, check the documentation.---------------------------
//------------------------------------------------------------------------------
//
//
//---------------preprocessing--------------------------------------------------
#define STRICT
#include<windows.h>
#include<stdio.h>
#include "qlp_wndproc.h" // the whole wndproc is defined extern
//END:-----------preprocessing--------------------------------------------------
//
//
//
//---------------global vars and funcs------------------------------------------
LRESULT CALLBACK MessFunc(HWND, UINT, WPARAM,LPARAM);
char szApNa[] = "Regions---the first trial";
//
//
//
//----------------trial: the class for the buttons-----not ready yet------------
/*class hoverrect
{
private:
RECT rpts;
static COLORREF bg;
static COLORREF bgh;
public:
hoverrect(int l, int t, int r, int b,SHORT bg,SHORT bgh);
int hovering();
~hoverrect();
};
// implementation-->
hoverrect::hoverrect(int l,int t,int r,int b,SHORT bg, SHORT bgh)
{
HWND wh = GetActiveWindow();
HDC hdc;
PAINTSTRUCT p;
bg = RGB(bg,bg,bg);
bgh = RGB(bgh,bgh,bgh);
hdc = BeginPaint(wh,&p);
Rectangle(hdc,l,t,r,b);
EndPaint(wh,&p);
}

int hoverrect::hovering()
{
}
hoverrect::~hoverrect()
{
}
// later this will be a class for a rectangle with button-hover-function
//-------------end of class-----------------------------------------------------
//
//
//
// END:--------------------global vars and funcs-------------------------------
//
*/

// --------------WinMain--------------------------------------------------------
int WINAPI WinMain(HINSTANCE hiact,HINSTANCE hiprev, LPSTR cmdline, int showhow)
{
MSG mess;
WNDCLASS wcx;
HWND thisone;

wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hiact;
wcx.lpfnWndProc = MessFunc;
wcx.lpszClassName = szApNa;
wcx.lpszMenuName = NULL;

wcx.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(120,140,200));
wcx.hIcon = NULL;
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.style = CS_VREDRAW | CS_HREDRAW;

if(!RegisterClass(&wcx))
{
MessageBox(NULL,"Error occured", "Registration failed",MB_OK);
return 0;
}


thisone = CreateWindow( szApNa,NULL, // attempt to hide the applications task bar
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,200,200,
NULL,
NULL,
hiact,
NULL
);
ShowWindow(thisone,showhow);
UpdateWindow(thisone);


while(GetMessage(&mess,NULL,0,0))
{
TranslateMessage(&mess);
DispatchMessage(&mess);
}
return mess.wParam;
}
// END: ------------------------WinMain-----------------------------------------
-
-
-

-
-
-
qlp_wndproc.h



// QLP:
//
// this file encapsules the whole WindowMessageProcedure.
// IMPORTANT TO DO:
// - why does the window fails when many WM_PAINTS are
// processed??? Must be changed.... MUST!!!!
// - dynamic height of window, if already picked entries would
// fill it
// STILL TO DO:
// - perhaps replace the 2 global variables by a perfect function
// - making usage of C++ by implementing the class hover for all buttons
//
//
//---------------------preprocessing--------------------------------------------
#include "qlp_flip.h" // important for all ressources
#include "qlp_dlgproc.h"
// END: --------------------preprocessing---------------------------------------
//
//

// global variables-------------------------------------------------------------
static COLORREF btnbg; // config button background
static bool pin; // switch for hovering


// END global variables---------------------------------------------------------
//
//
//----------------WndProc , named MessFunc -------------------------------------
LRESULT CALLBACK MessFunc(HWND mwinhan,UINT mcode, WPARAM wm_Wflags,LPARAM wm_Lflags)
{

static HRGN h3rgn;

static POINT a,b,c,d,e,f;
a.x=110; a.y=30;
b.x=180; b.y=70;
c.x=180; c.y=150;
d.x=110; d.y=190;
e.x=40; e.y=150;
f.x=40; f.y=70;

// the default-button:config--------------------------------------------------
static POINT ab,bb,cb;
ab.x=e.x+10; ab.y=128;
bb.x=c.x-18; bb.y=128;
cb.x= d.x-3; cb.y=d.y-30;

static POINT bpt[2] ;
bpt[0] = ab;
bpt[1] = bb;
bpt[2] = cb;


// as a region to allow hover effects and bitmap manipulations
//END: btn_config ------------------------------------------------------------

POINT psxy; // to store the mouse coordinates in / not to make static, why?

//-----statics needed local for identification to clip bmp---------------------
static HBITMAP oldbmp;
static HBITMAP hskin;
static HDC dcskin;

// END: local statics---------------------------------------------------------
//
// the switch loop------------------------------------------------------------
switch(mcode)
{
case WM_CREATE:
{
// region for hektagon--------------------------------------------------
const POINT pt[] = {a,b,c,d,e,f}; // here the points are used
HRGN rg1 = CreatePolygonRgn(pt,6,ALTERNATE);
SetWindowRgn(mwinhan,rg1,true);
DeleteObject(rg1); // who knows, why??
// END: hektagon region-------------------------------------------------
//
// attaching bmp-skin to hektagon region and special device context-----
hskin = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_BMP));
dcskin = CreateCompatibleDC(0);
oldbmp = (HBITMAP)SelectObject(dcskin,hskin);
// END: attach----------------------------------------------------------
//
// changing window style by its class-----------------------------------
DWORD wndstyle = GetWindowLong(mwinhan,GWL_STYLE);
// a very good and versatile function : with this function
// we can retrieve several information about our used window class
// it is also possible to retrieve information about predefined
// classes like button or edit and to subclass them.
wndstyle &=~(WS_CAPTION | WS_SIZEBOX);
// very smooth: our overlapped window is now getting cut short and the
// here mentioned elements are removed by an bit addition, using a
//~ to remove and a pipe to line up, which we will remove
SetWindowLong(mwinhan,GWL_STYLE,wndstyle);
// here we replace the former Window style by this, which we have
// defined one line before, now we have an overlapped window without
// a caption bar and without the possbility to resize it.

char ch[10];
if(!hskin)
{
MessageBox(NULL,itoa(GetLastError(),ch,10),"Error",MB_OK);
return 0;
}

// setting default-color for config-btn, defining state

btnbg = (RGB(255,255,255));
pin = false;
h3rgn = CreatePolygonRgn(bpt,3,WINDING);

break;
}
// end:changing windowstyle-------------------------------------------------
//--------------------------------------------------------------------------
case WM_LBUTTONDOWN:
{

if(PtInRegion(h3rgn,LONG(LOWORD(wm_Lflags)),LONG(HIWORD(wm_Lflags))) != 0)
{
DialogBox(GetModuleHandle(NULL),MAKEINTRESOURCE(ID_DLG_CONF),mwinhan,(DLGPROC)DlgProc);
}
break;
}
case WM_MOUSEMOVE:
{
// getting mousecoordinates while moving--------------------------------
psxy.x = LONG(LOWORD(wm_Lflags));
psxy.y = LONG(HIWORD(wm_Lflags));
// END: getting mousecoordinates----------------------------------------
//
// hovering not optimized, it flickers
// a redraw is not neccessary, if the mouse is not in a region
// but moves inside the hektagon. This must be implemented.
// idea: InvalidateRegion........UpdateRegion, or a switch for
// binary comparison or a Mousetrace
//-------------------------the trial-------------------------------------------
//-------------------------the trial-------------------------------------------

if((PtInRegion(h3rgn,psxy.x, psxy.y) != 0) && (pin == false))
{
pin = true;
btnbg = (RGB(125,125,125));
InvalidateRgn(mwinhan,h3rgn,false);
UpdateWindow(mwinhan);
//RedrawWindow(mwinhan,NULL,h3rgn,RDW_INTERNALPAINT);
}
if((PtInRegion(h3rgn,psxy.x, psxy.y) == 0) && (pin == true ))
{
pin = false;
btnbg = (RGB(255,255,255));
InvalidateRgn(mwinhan,h3rgn,false);
UpdateWindow(mwinhan);
//RedrawWindow(mwinhan,NULL,h3rgn,RDW_INTERNALPAINT);
}
DeleteObject(h3rgn);
//----------not optimized: use a locale-------------------------------------
break;
}
case WM_PAINT:
{
// blitting the attached skin to the hektagon region -------------------
//RECT wnd6;
//GetWindowRect(mwinhan,&wnd6);
static HDC hdc;
static PAINTSTRUCT pskn;
static HBRUSH selbr; // to store the brush for later use
hdc = BeginPaint(mwinhan,&pskn);
//BitBlt(pskn.hdc,0,0,200,200,dcskin,-10,-5,SRCCOPY);
// end: blitting skin------------------------------------------------
// creating default button for config with caption ------------------
selbr = (HBRUSH)SelectObject(hdc,(HBRUSH)CreateSolidBrush((COLORREF)btnbg)) ;
Polygon(hdc,bpt,3);
SetBkMode(hdc,TRANSPARENT);
TextOut(hdc,(bb.x/2)+3,ab.y+2,"Config", 6);
DeleteObject(SelectObject(hdc,selbr));
EndPaint(mwinhan, &pskn);
ReleaseDC(mwinhan,hdc);

//end: button with caption----------------------------------------------
// not optimized, but it works------------------------------------------

break;
}
case WM_DESTROY:
{

PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(mwinhan,mcode,wm_Wflags,wm_Lflags);
}

MaxPower
January 25th, 2008, 06:24 PM
Just in case you're unaware of this, the code you posted has hundreds and hundreds of extraneous dashes in it.

me-$-on
January 28th, 2008, 04:18 AM
unaware?
You are kidding me......
-
That's why i ask ...
-
What errors for exampe do You mean?
( Need not to show me all errors.. and don't mind the class, i've tried to build..... this is not used now and will be corrected later).
-
Because i came that far, to kill the op-error ( original posted error ), by adding a DeleteObject at the beginnig of the WM_PAINT and a CreateRgn, so the object will be created after being killed..... otherwise it does not work.... or at least i chose this possibility, to clean up the object...... means, it will be created, but destroyed in the next WM_PAINT, which will be intercepted.
-
So, now i have to correct the clipping region and adjust the window rectangle, because i found already some more errors.
Although deleting the caption and the sizebox, this change takes only effect, it the desktop window becomes top window, and after that my app comes on top again. ( who kows , why )
Means, directly after I start my app, there is now titlebar and caption.
But if i use alt-tab to switch between apps, there suddenly appears a titlebar, grey and not to use. As long i'm switching between apps, this titlebar remains, if i set my focus on my app, the titlebard disappears, until i switch again between apps.
!!!!!
If i chose windows+d keycombination, i go to my desktop........ if i go to my application after having been on the desktop, there is no more titlebar , but the small triangle, which shall be my button, slided a little bit upwards and a little bit leftwards. Exaxtly the amount of the titlebar and the border.
Means, the WM_CREATE does not do all things that i want..... and the window metrics are computed with border and titlebar, although i deleted them. Because of that the window appears to be wrong measured, and because of that the triangle "walks" away.
Will try and check for more errors..
-
What else did You find?
-
Thanks so far!