How to set z order of custom window to top which attached with active window?

326 views
Skip to first unread message

varsha

unread,
Dec 18, 2008, 12:24:18 AM12/18/08
to Win32 Programming
Hi,


I tried to add button onto titlebar of any window.

I properly sets custom window onto title bar of active window. but
after sometime zorder of custom widow will be change and it goes to
back of the title bar.

How to solve this problem if anybody have idea about this please help
me!!!!!!!!

my code
1] I created custom window using cretaewindowx

hwnd=CreateWindowEx(WS_EX_NOACTIVATE,// | WS_EX_TOOLWINDOW,
szAppName, // window class name
szAppName, // window caption
WS_DLGFRAME , // window style
//WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION,

100, // initial x position
0, // initial y position
1, // initial x size
2, // initial y size
NULL, // parent window handle
NULL, // use window class menu
hInst, // program instance handle
NULL); // creation parameters

lStyle = GetWindowLong(hwnd, GWL_STYLE);
lStyle &= WS_CHILD;
lStyle &=~WS_MINIMIZEBOX,


SetWindowLong(hwnd, GWL_STYLE, lStyle);
SetWindowPos(hwnd,HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE |
SWP_NOCOPYBITS | SWP_NOSENDCHANGING |
SWP_NOSIZE | SWP_ASYNCWINDOWPOS |
SWP_NOOWNERZORDER);

---------------------------------------------------------------------------------------------------------------------------------------------------------
2] Then I used SetWindowsHookEx() to hook the active window procedure

my active window hook proc is

__declspec( dllexport ) CALLBACK CallWndRetProc( int code, WPARAM wp,
LPARAM lp )
{
DWORD style;
HDC hdc;
UINT uButType;
RECT rect1;
LONG AppOrigExStyle;


if( code == HC_ACTION )
{
const CWPRETSTRUCT* cwp = (CWPRETSTRUCT*)lp;
switch( cwp->message )
{

case WM_ACTIVATE:
if( LOWORD( cwp->wParam ) != WA_INACTIVE )
{


/* Change the window styles to hide the media player from the task
bar:
need to hide the window before making the change and then make it
visible again - works for Winamp and Windows Media Player but
those windows have custom title bars - this might do weird things
where the window has a more normal title bar... */
//ShowWindow( PositionerWindow, SW_HIDE );
AppOrigExStyle = GetWindowLong( PositionerWindow, GWL_EXSTYLE );
SetWindowLong( PositionerWindow, GWL_EXSTYLE, ( AppOrigExStyle &
~WS_EX_APPWINDOW ) );
SetWindowPos(PositionerWindow,HWND_TOP, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOSENDCHANGING |
SWP_NOSIZE | SWP_ASYNCWINDOWPOS |
SWP_NOOWNERZORDER| SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);

ShowWindow( PositionerWindow, SW_SHOW );


PostMessage( PositionerWindow, UPDATE_MSG, (WPARAM)cwp->hwnd, 1 );
LOG((_T("in activate")));
}
else
{
ShowWindow( PositionerWindow, SW_HIDE );
}

break;


case WM_WINDOWPOSCHANGED:
if( cwp->hwnd == MostRecentWindow )
{

/* Change the window styles to hide the media player from the task
bar:
need to hide the window before making the change and then make
it
visible again - works for Winamp and Windows Media Player but
those windows have custom title bars - this might do weird
things
where the window has a more normal title bar... */
AppOrigExStyle = GetWindowLong( PositionerWindow, GWL_EXSTYLE );
SetWindowLong( PositionerWindow, GWL_EXSTYLE, ( AppOrigExStyle &
~WS_EX_APPWINDOW ) );
SetWindowPos(PositionerWindow,HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE |
SWP_NOCOPYBITS | SWP_NOSENDCHANGING |
SWP_NOSIZE | SWP_ASYNCWINDOWPOS |
SWP_NOOWNERZORDER| SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
ShowWindow( PositionerWindow, SW_SHOW );

PostMessage( PositionerWindow, UPDATE_MSG, (WPARAM)cwp->hwnd, 2 );
LOG((_T("in positionchanged")));
}
break;
} /* end switch message */
} /* end if action */

return CallNextHookEx( PrevHook, code, wp, lp );
}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
custom window procedure is as following


LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
lParam)
{
TCHAR szText[80];
HBITMAP hBmp1, hBmp2;

int right, top;
switch(msg)
{
case WM_CREATE:

// These must be MONOCHROME bitmaps if you want them
// to be drawn nicely.
hBmp2 = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE
(IDB_BITMAP2));
Caption_InsertButton(hwnd, 2, 2, hBmp2);
return 0;

case UPDATE_MSG:
/* Only do something if the config window is hidden, and don't
react to
the window we're hooking! */
/*if( IsWindowVisible( hwnd ) || (HWND)wParam == hd )
return 0;*/

if( IsWindowSuitable( (HWND)wParam ) && IsPositionOK( (HWND)wParam,
&right, &top ) )
{
hd=hwnd;
Attach( (HWND)wParam, right, top );

wsprintf(szText, _T("%s %d "), szAppName, lParam);
LOG((szText,"\n")) ;
return 0;
}

return 0;

case WM_COMMAND:

/*wsprintf(szText, _T("%s %d [%d, %d]"), szAppName, wParam, LOWORD
(lParam), HIWORD(lParam));
SetWindowText(hd, szText);*/
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

case WM_CLOSE:
DestroyWindow(hwnd);
return 0;
}

return DefWindowProc(hwnd, msg, wParam, lParam);
}




/* Move the window into place */


void GetMetrics( void )
{
sm_CXSIZE = GetSystemMetrics( SM_CXSIZE );
sm_CYSIZE = GetSystemMetrics( SM_CYSIZE );
sm_CXSIZEFRAME = GetSystemMetrics( SM_CXSIZEFRAME );
sm_CXFIXEDFRAME = GetSystemMetrics( SM_CXFIXEDFRAME );
sm_CYSIZEFRAME = GetSystemMetrics( SM_CYSIZEFRAME );
sm_CYFIXEDFRAME = GetSystemMetrics( SM_CYFIXEDFRAME );
sm_CXFULLSCREEN = GetSystemMetrics( SM_CXFULLSCREEN );
}




/* Most captioned windows have things like minimise or close buttons
on
the right: this routine calculates the width of these features on
the
passed in window. Because the callers of this routine typically use
the style already, this function accepts that as an argument too, a
bit quicker than getting it again. Unfortunately, not all the sizes
associated with the placement of these features are defined by
Windows
metrics, so some, I am afraid, are just magic numbers found by
careful
measurement. Additionally, I grab the other sizes every time,
instead
of caching them, just in case they are changed under my feet! */

static int WindowsFeaturesWidth( HWND hwnd, DWORD style )
{
/* The reasoning behind this is: if a Window has a system menu
specified,
it'll have a close button; additionally it can have nothing else
OR a
help button OR both minimise and maximise buttons, and in that
latter
case, the buttons are adjacent so trim off the inter-button
spacing.
Note that the buttons are actually 2 pixels smaller than the
system
metric, as it appears that that includes the spacing. */
int width = 2 + ( ( style & WS_THICKFRAME ) ? sm_CXSIZEFRAME :
sm_CXFIXEDFRAME );
if( style & WS_SYSMENU )
width += sm_CXSIZE;
/* I think I should be able to check for maximise and minimise
buttons
separately, but some applications (all?), such as calculator,
display
both even though one is not enabled - since it's better to have a
gap
I assume that if one's there both are */
if( style & ( WS_MAXIMIZEBOX | WS_MINIMIZEBOX ) )
width += sm_CXSIZE * 2 - 2; /* -2 since the buttons touch */
else if( GetWindowLong( hwnd, GWL_EXSTYLE ) & WS_EX_CONTEXTHELP )
width += sm_CXSIZE;

return width;
}

/* Move the window into place */
static void Position( int top, int right )
{


RECT r;

DWORD a;
BOOL ff;

if( GetWindowRect( hd, &r ) )
AppWindowWidth = r.right - r.left;

left1 = right - 0 - AppWindowWidth;

if( left1 < 0 )
left1 = 0;
top += 0;
if( top < 0 )
top = 0;
/* TODO - make sure it doesn't fall off the right or bottom either
*/
//LOG(( _T("Moving to %d,%d\n"), left, top ));


ff=SetWindowPos( hd, HWND_TOP,
left1, top, 30, 20,
SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOSENDCHANGING |
SWP_ASYNCWINDOWPOS | SWP_NOOWNERZORDER );

}


static void Attach( HWND hwnd, int right, int top )
{
DWORD style = GetWindowLong( hwnd, GWL_STYLE );

right -= WindowsFeaturesWidth( hwnd, style );
top += ( ( style & WS_THICKFRAME ) ? sm_CYSIZEFRAME :
sm_CYFIXEDFRAME );

Position( top, right );
MostRecentWindow = hwnd;
}


static BOOL IsPositionOK( HWND hwnd, /*[out]*/ int* right, /*[out]*/
int* top )
{
RECT r;
GetWindowRect( hwnd, &r );

/* Window is offscreen - that's no use! */
/* TODO - check of off bottom too */
if( r.right < 0 || r.left > sm_CXFULLSCREEN || r.bottom < 0 )
return FALSE;

*right = r.right;
*top = r.top;
return TRUE;
}



Thanks and Regards
Varsha

Report post as abusive
Reply all
Reply to author
Forward
0 new messages