/*
Miranda IM: the free IM client for Microsoft* Windows*

Copyright 2000-2008 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "hdr/modern_commonheaders.h"
#include "m_api/m_skin_eng.h"
#include "hdr/modern_cluiframes.h"
#include "hdr/modern_commonprototypes.h"
#include "hdr/modern_sync.h"


// ALL THIS MODULE FUNCTION SHOULD BE EXECUTED FROM MAIN THREAD

#include "hdr/modern_static_cluiframes_service.h" // contain services initialization and proxiation


static const int UNCOLLAPSED_FRAME_SIZE		= 0;
static const int DEFAULT_TITLEBAR_HEIGHT	= 18;

//GLOBALS
FRAMEWND *	g_pfwFrames		= NULL;
int			g_nFramesCount	= 0;
int			g_nTitleBarHeight = DEFAULT_TITLEBAR_HEIGHT;

// STATIC

enum {
	frame_menu_lock = 1,
	frame_menu_visible,
	frame_menu_showtitlebar,
	frame_menu_floating
}; //legacy menu support

enum { eUnknownId = -1 };

static int	_us_DoSetFrameFloat( WPARAM wParam,LPARAM lParam );
static int	CLUIFrameResizeFloatingFrame( int framepos );
static HWND CreateSubContainerWindow( HWND parent,int x,int y,int width,int height );
static BOOL CLUIFramesFitInSize();
static int  RemoveItemFromList(int pos, FRAMEWND **lpFrames, int *FrameItemCount );
static int  _us_DoSetFramePaintProc(WPARAM wParam, LPARAM lParam);



static CRITICAL_SECTION _cluiFramesModuleCS				= {0};
static BOOL				_cluiFramesModuleCSInitialized	= FALSE;
static BOOL				_fCluiFramesModuleNotStarted	= TRUE;
static XPTHANDLE		_hFrameTitleTheme				= NULL;
static int				_nClientFrameId					= eUnknownId; //for fast access to frame with alclient properties
static int				_iNextFrameId					= 100;
static HFONT			_hTitleBarFont					= NULL;

// menus
static HGENMENU _hmiVisible		= (HGENMENU)-1;
static HGENMENU _hmiTBVisible		= (HGENMENU)-1;
static HGENMENU _hmiLock			= (HGENMENU)-1;
static HGENMENU _hmiColl			= (HGENMENU)-1;
static HGENMENU _hmiFloating		= (HGENMENU)-1;
static HGENMENU _hmiAlignRoot		= (HGENMENU)-1;
static HGENMENU _hmiAlignTop		= (HGENMENU)-1;
static HGENMENU _hmiAlignClient	= (HGENMENU)-1;
static HGENMENU _hmiAlignBottom	= (HGENMENU)-1;
static HGENMENU _hmiPosRoot		= (HGENMENU)-1;
static HGENMENU _hmiPosUp			= (HGENMENU)-1;
static HGENMENU _hmiPosDown		= (HGENMENU)-1;
static HGENMENU _hmiBorder       = (HGENMENU)-1;
static HGENMENU _hmiRoot			= (HGENMENU)-1;

// others
static int _nContactListHeight	= 0;
static DWORD _dwLastStoreTick	= 0;

HWND hWndExplorerToolBar;
static int GapBetweenFrames=1;

BOOLEAN bMoveTogether;
int recurs_prevent=0;
static BOOL PreventSizeCalling=FALSE;

static HBITMAP hBmpBackground;
static int backgroundBmpUse;
static COLORREF bkColour;
static COLORREF SelBkColour;
static BOOL bkUseWinColours;
boolean AlignCOLLIconToLeft; //will hide frame icon
COLORREF sttGetColor(char * module, char * color, COLORREF defColor);
//for old multiwindow
#define MPCF_CONTEXTFRAMEMENU		3
POINT ptOld;
short	nLeft			= 0;
short	nTop			= 0;

static int sortfunc(const void *a,const void *b)
{
	SortData *sd1,*sd2;
	sd1=(SortData *)a;
	sd2=(SortData *)b;
	if (sd1->order > sd2->order){return(1);};
	if (sd1->order < sd2->order){return(-1);};
	return (0);
};
int CLUIFrames_OnMoving( HWND hwnd, RECT * r)
{
	int i;
	g_CluiData.mutexPreventDockMoving=0;
	for(i=0;i<g_nFramesCount;i++) {

		if (!g_pfwFrames[i].floating && g_pfwFrames[i].OwnerWindow!=NULL &&g_pfwFrames[i].OwnerWindow!=(HWND)-2)
		{
			int x;
			int y;
			int dx,dy;
			FRAMEWND * Frame;
			POINT pt={0};
			RECT wr;
			Frame=&(g_pfwFrames[i]);

			GetWindowRect(hwnd,&wr);
			ClientToScreen(hwnd,&pt);
			dx=(r->left-wr.left)+pt.x;
			dy=(r->top-wr.top)+pt.y;
			x=Frame->wndSize.left;
			y=Frame->wndSize.top;
			SetWindowPos(Frame->OwnerWindow,NULL,x+dx,y+dy,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSENDCHANGING|SWP_ASYNCWINDOWPOS|SWP_DEFERERASE|SWP_NOOWNERZORDER);
		};

	}
	g_CluiData.mutexPreventDockMoving=1;
	AniAva_RedrawAllAvatars(FALSE);
	return 0;
}
int SetAlpha(BYTE Alpha)
{
	int i;

	for(i=0;i<g_nFramesCount;i++) {

		if (!g_pfwFrames[i].floating && g_pfwFrames[i].OwnerWindow!=NULL &&g_pfwFrames[i].OwnerWindow!=(HWND)-2 && g_pfwFrames[i].visible && !g_pfwFrames[i].needhide )
		{
			HWND hwnd=g_pfwFrames[i].OwnerWindow;
			if (g_proc_SetLayeredWindowAttributesNew)
			{
				long l;
				l=GetWindowLongPtr(hwnd,GWL_EXSTYLE);
				if (!(l&WS_EX_LAYERED))
				{
					HWND parent=NULL;
					if (g_CluiData.fOnDesktop)
					{
						HWND hProgMan=FindWindow(TEXT("Progman"),NULL);
						if (IsWindow(hProgMan))
							parent=hProgMan;
					}

					CLUI_ShowWindowMod(hwnd,SW_HIDE);
					SetParent(hwnd,NULL);
					SetWindowLongPtr(hwnd,GWL_EXSTYLE,l|WS_EX_LAYERED);
					SetParent(hwnd,parent);
					if (l&WS_VISIBLE)  CLUI_ShowWindowMod(hwnd,SW_SHOW);
				}
				g_proc_SetLayeredWindowAttributesNew(hwnd, g_CluiData.dwKeyColor,Alpha, LWA_ALPHA|LWA_COLORKEY);
			}
		}
	}
	AniAva_RedrawAllAvatars(FALSE);
	return 0;
}


int CLUIFrames_RepaintSubContainers()
{
	int i;
	for(i=0;i<g_nFramesCount;i++)
		if (!g_pfwFrames[i].floating && g_pfwFrames[i].OwnerWindow!=(HWND)0 &&g_pfwFrames[i].OwnerWindow!=(HWND)-2 && g_pfwFrames[i].visible && !g_pfwFrames[i].needhide )
		{
			RedrawWindow(g_pfwFrames[i].hWnd,NULL,NULL,RDW_ALLCHILDREN|RDW_UPDATENOW|RDW_INVALIDATE|RDW_FRAME);
		};
	return 0;
}

int CLUIFrames_ActivateSubContainers( BOOL active)
{
	int i;
	for(i=0;i<g_nFramesCount;i++)
		if (active&&!g_pfwFrames[i].floating && g_pfwFrames[i].OwnerWindow!=(HWND)0 &&g_pfwFrames[i].OwnerWindow!=(HWND)-2 && g_pfwFrames[i].visible && !g_pfwFrames[i].needhide )
		{
			HWND hwnd=g_pfwFrames[i].OwnerWindow;
			hwnd=g_pfwFrames[i].hWnd;//OwnerWindow;
			if (db_get_b(NULL,"CList","OnDesktop",SETTING_ONDESKTOP_DEFAULT))
			{
				SetWindowPos(g_pfwFrames[i].OwnerWindow,HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
				SetWindowPos(g_pfwFrames[i].OwnerWindow,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
			}
			else SetWindowPos(g_pfwFrames[i].OwnerWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOSIZE | SWP_NOMOVE);
		};
	return 0;
}
int CLUIFrames_SetParentForContainers( HWND parent )
{
	int i;
	if (parent&&parent!=pcli->hwndContactList)
		g_CluiData.fOnDesktop=1;
	else
		g_CluiData.fOnDesktop=0;
	for(i=0;i<g_nFramesCount;i++) {
		if (!g_pfwFrames[i].floating && g_pfwFrames[i].OwnerWindow!=(HWND)0 &&g_pfwFrames[i].OwnerWindow!=(HWND)-2 && g_pfwFrames[i].visible && !g_pfwFrames[i].needhide )
		{
			HWND hwnd=g_pfwFrames[i].OwnerWindow;
			SetParent(hwnd,parent);
		}
	}
	return 0;
}

int CLUIFrames_OnShowHide( HWND hwnd, int mode )
{
	int i;
	int prevFrameCount;
	for(i=0;i<g_nFramesCount;i++) {
		if (!g_pfwFrames[i].floating && g_pfwFrames[i].OwnerWindow!=(HWND)0 &&g_pfwFrames[i].OwnerWindow!=(HWND)-2)
		{
			{
				//Try to avoid crash on exit due to unlock.
				HWND owner=g_pfwFrames[i].OwnerWindow;
				HWND Frmhwnd=g_pfwFrames[i].hWnd;
				BOOL visible=g_pfwFrames[i].visible;
				BOOL needhide=g_pfwFrames[i].needhide;
				needhide |= (!g_pfwFrames[i].collapsed || g_pfwFrames[i].height == 0 );
				prevFrameCount=g_nFramesCount;
				ShowWindow(owner,(mode==SW_HIDE||!visible||needhide)?SW_HIDE:mode);
				ShowWindow(Frmhwnd,(mode==SW_HIDE||!visible||needhide)?SW_HIDE:mode);
			}

			if (mode!=SW_HIDE)
			{
				SetWindowPos(g_pfwFrames[i].OwnerWindow,HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
				if (db_get_b(NULL,"CList","OnDesktop",SETTING_ONDESKTOP_DEFAULT))
				{
					SetWindowPos(g_pfwFrames[i].OwnerWindow,HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
					SetWindowPos(g_pfwFrames[i].OwnerWindow,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
				}
				else SetWindowPos(g_pfwFrames[i].OwnerWindow, HWND_NOTOPMOST, 0, 0, 0, 0,SWP_NOACTIVATE|SWP_NOSIZE | SWP_NOMOVE);
			}
		}
	}
	if (mode!=SW_HIDE) SetForegroundWindow(pcli->hwndContactList);
	AniAva_RedrawAllAvatars(TRUE);
	return 0;
}
static int RemoveItemFromList(int pos,FRAMEWND **lpFrames,int *FrameItemCount)
{
	memmove(&((*lpFrames)[pos]),&((*lpFrames)[pos+1]),sizeof(FRAMEWND)*(*FrameItemCount-pos-1));
	(*FrameItemCount)--;
	(*lpFrames)=(FRAMEWND*)realloc((*lpFrames),sizeof(FRAMEWND)*(*FrameItemCount));
	return 0;
}

static int id2pos(int id)
{
	int i;
	if (_fCluiFramesModuleNotStarted) return -1;
	for (i=0;i<g_nFramesCount;i++)
		if (g_pfwFrames[i].id==id) return(i);
	return(-1);
};

static int btoint(BOOLEAN b)
{
	if(b) return 1;
	return 0;
}


static FRAMEWND* FindFrameByWnd( HWND hwnd )
{
	int i;

	if ( hwnd == NULL ) return( NULL );

	for(i=0;i<g_nFramesCount;i++)
		if ((g_pfwFrames[i].floating)&&(g_pfwFrames[i].ContainerWnd==hwnd))
			return(&g_pfwFrames[i]);

	return( NULL);
}


int QueueAllFramesUpdating(BYTE queue)
{
	int i;
	for(i=0;i<g_nFramesCount;i++)
	{
		if (!g_CluiData.fLayered)
		{
			if (queue)
				InvalidateRect(g_pfwFrames[i].hWnd,NULL,FALSE);
			else
				ValidateRect(g_pfwFrames[i].hWnd,NULL);
		}
		if (g_pfwFrames[i].PaintCallbackProc)
		{
			g_pfwFrames[i].bQueued=queue;
			if (g_pfwFrames[i].UpdateRgn)
			{
				DeleteObject(g_pfwFrames[i].UpdateRgn);
			}
			g_pfwFrames[i].UpdateRgn=0;
		}

	}
	return queue;

}
int FindFrameID(HWND FrameHwnd)
{
	FRAMEWND * frm=NULL;
	if (FrameHwnd == NULL ) return 0;
	frm=FindFrameByItsHWND(FrameHwnd);
	if (frm)
		return frm->id;
	else return 0;
}
FRAMEWND * FindFrameByItsHWND(HWND FrameHwnd)
{
	int i;
	if ( FrameHwnd == NULL ) return( NULL );
	for(i=0;i<g_nFramesCount;i++)
	{
		if (g_pfwFrames[i].hWnd==FrameHwnd){return(&g_pfwFrames[i]);};
	};
	return NULL;
}

static void DockThumbs( FRAMEWND *pThumbLeft, FRAMEWND *pThumbRight, BOOL bMoveLeft )
{
	if ( ( pThumbRight->dockOpt.hwndLeft == NULL ) && ( pThumbLeft->dockOpt.hwndRight == NULL ))
	{
		pThumbRight->dockOpt.hwndLeft	= pThumbLeft->ContainerWnd;
		pThumbLeft->dockOpt.hwndRight	= pThumbRight->ContainerWnd;
	}
}


static void UndockThumbs( FRAMEWND *pThumb1, FRAMEWND *pThumb2 )
{
	if ( ( pThumb1 == NULL ) || ( pThumb2 == NULL ))
	{
		return;
	}

	if ( pThumb1->dockOpt.hwndRight == pThumb2->ContainerWnd )
	{
		pThumb1->dockOpt.hwndRight = NULL;
	}

	if ( pThumb1->dockOpt.hwndLeft == pThumb2->ContainerWnd )
	{
		pThumb1->dockOpt.hwndLeft = NULL;
	}

	if ( pThumb2->dockOpt.hwndRight == pThumb1->ContainerWnd )
	{
		pThumb2->dockOpt.hwndRight = NULL;
	}

	if ( pThumb2->dockOpt.hwndLeft == pThumb1->ContainerWnd )
	{
		pThumb2->dockOpt.hwndLeft = NULL;
	}
}
static void PositionThumb( FRAMEWND *pThumb, short nX, short nY )
{
	FRAMEWND	*pCurThumb	= &g_pfwFrames[0];
	FRAMEWND	*pDockThumb	= pThumb;
	FRAMEWND	fakeMainWindow;
	FRAMEWND	fakeTaskBarWindow;
	RECT		rc;
	RECT		rcThumb;
	RECT		rcOld;
	SIZE		sizeScreen;
	int			nNewX;
	int			nNewY;
	int			nOffs		= 10;
	int			nWidth;
	int			nHeight;
	POINT		pt;
	RECT		rcLeft;
	RECT		rcTop;
	RECT		rcRight;
	RECT		rcBottom;
	BOOL		bDocked;
	BOOL		bDockedLeft;
	BOOL		bDockedRight;
	BOOL		bLeading;
	int			frmidx=0;

	if ( pThumb == NULL ) return;

	sizeScreen.cx = GetSystemMetrics( SM_CXSCREEN );
	sizeScreen.cy = GetSystemMetrics( SM_CYSCREEN );

	// Get thumb dimnsions
	GetWindowRect( pThumb->ContainerWnd, &rcThumb );
	nWidth	= rcThumb.right - rcThumb.left;
	nHeight = rcThumb.bottom - rcThumb.top;

	// Docking to the edges of the screen
	nNewX = nX < nOffs ? 0 : nX;
	nNewX = nNewX > ( sizeScreen.cx - nWidth - nOffs ) ? ( sizeScreen.cx - nWidth ) : nNewX;
	nNewY = nY < nOffs ? 0 : nY;
	nNewY = nNewY > ( sizeScreen.cy - nHeight - nOffs ) ? ( sizeScreen.cy - nHeight ) : nNewY;

	bLeading = pThumb->dockOpt.hwndRight != NULL;

	if ( bMoveTogether )
	{
		UndockThumbs( pThumb,  FindFrameByWnd( pThumb->dockOpt.hwndLeft ));
		GetWindowRect( pThumb->ContainerWnd, &rcOld );
	}

	memset(&fakeMainWindow,0,sizeof(fakeMainWindow));
	fakeMainWindow.ContainerWnd=pcli->hwndContactList;
	fakeMainWindow.floating=TRUE;

	memset(&fakeTaskBarWindow,0,sizeof(fakeTaskBarWindow));
	fakeTaskBarWindow.ContainerWnd=hWndExplorerToolBar;
	fakeTaskBarWindow.floating=TRUE;


	while( pCurThumb != NULL )
	{
		if (pCurThumb->floating) {

			if ( pCurThumb != pThumb )
			{
				GetWindowRect( pThumb->ContainerWnd, &rcThumb );
				OffsetRect( &rcThumb, nX - rcThumb.left, nY - rcThumb.top );

				GetWindowRect( pCurThumb->ContainerWnd, &rc );

				// These are rects we will dock into

				rcLeft.left		= rc.left - nOffs;
				rcLeft.top		= rc.top - nOffs;
				rcLeft.right	= rc.left + nOffs;
				rcLeft.bottom	= rc.bottom + nOffs;

				rcTop.left		= rc.left - nOffs;
				rcTop.top		= rc.top - nOffs;
				rcTop.right		= rc.right + nOffs;
				rcTop.bottom	= rc.top + nOffs;

				rcRight.left	= rc.right - nOffs;
				rcRight.top		= rc.top - nOffs;
				rcRight.right	= rc.right + nOffs;
				rcRight.bottom	= rc.bottom + nOffs;

				rcBottom.left	= rc.left - nOffs;
				rcBottom.top	= rc.bottom - nOffs;
				rcBottom.right	= rc.right + nOffs;
				rcBottom.bottom = rc.bottom + nOffs;


				bDockedLeft		= FALSE;
				bDockedRight	= FALSE;

				// Upper-left
				pt.x	= rcThumb.left;
				pt.y	= rcThumb.top;
				bDocked	= FALSE;

				if ( PtInRect( &rcRight, pt ))
				{
					nNewX	= rc.right;
					bDocked = TRUE;
				}

				if ( PtInRect( &rcBottom, pt ))
				{
					nNewY = rc.bottom;

					if ( PtInRect( &rcLeft, pt ))
					{
						nNewX = rc.left;
					}
				}

				if ( PtInRect( &rcTop, pt ))
				{
					nNewY		= rc.top;
					bDockedLeft	= bDocked;
				}

				// Upper-right
				pt.x	= rcThumb.right;
				pt.y	= rcThumb.top;
				bDocked	= FALSE;

				if ( !bLeading && PtInRect( &rcLeft, pt ))
				{
					if ( !bDockedLeft )
					{
						nNewX	= rc.left - nWidth;
						bDocked	= TRUE;
					}
					else if ( rc.right == rcThumb.left )
					{
						bDocked = TRUE;
					}
				}


				if ( PtInRect( &rcBottom, pt ))
				{
					nNewY = rc.bottom;

					if ( PtInRect( &rcRight, pt ))
					{
						nNewX = rc.right - nWidth;
					}
				}

				if ( !bLeading && PtInRect( &rcTop, pt ))
				{
					nNewY			= rc.top;
					bDockedRight	= bDocked;
				}

				if ( bMoveTogether )
				{
					if ( bDockedRight )
					{
						DockThumbs( pThumb, pCurThumb, TRUE );
					}

					if ( bDockedLeft )
					{
						DockThumbs( pCurThumb, pThumb, FALSE );
					}
				}

				// Lower-left
				pt.x = rcThumb.left;
				pt.y = rcThumb.bottom;

				if ( PtInRect( &rcRight, pt ))
				{
					nNewX = rc.right;
				}

				if ( PtInRect( &rcTop, pt ))
				{
					nNewY = rc.top - nHeight;

					if ( PtInRect( &rcLeft, pt ))
					{
						nNewX = rc.left;
					}
				}


				// Lower-right
				pt.x = rcThumb.right;
				pt.y = rcThumb.bottom;

				if ( !bLeading && PtInRect( &rcLeft, pt ))
				{
					nNewX = rc.left - nWidth;
				}

				if ( !bLeading && PtInRect( &rcTop, pt ))
				{
					nNewY = rc.top - nHeight;

					if ( PtInRect( &rcRight, pt ))
					{
						nNewX = rc.right - nWidth;
					}
				}
			}

		};
		frmidx++;
		if (pCurThumb->ContainerWnd==fakeTaskBarWindow.ContainerWnd){break;};
		if (pCurThumb->ContainerWnd==fakeMainWindow.ContainerWnd){
			pCurThumb=&fakeTaskBarWindow;continue;};
			if (frmidx==g_nFramesCount){
				pCurThumb=&fakeMainWindow;continue;
			}

			pCurThumb = &g_pfwFrames[frmidx];



	}

	// Adjust coords once again
	nNewX = nNewX < nOffs ? 0 : nNewX;
	nNewX = nNewX > ( sizeScreen.cx - nWidth - nOffs ) ? ( sizeScreen.cx - nWidth ) : nNewX;
	nNewY = nNewY < nOffs ? 0 : nNewY;
	nNewY = nNewY > ( sizeScreen.cy - nHeight - nOffs ) ? ( sizeScreen.cy - nHeight ) : nNewY;


	SetWindowPos(	pThumb->ContainerWnd,
		HWND_TOPMOST,
		nNewX,
		nNewY,
		0,
		0,
		SWP_NOSIZE | SWP_NOZORDER|SWP_NOACTIVATE );


	// OK, move all g_CluiData.fDocked thumbs
	if ( bMoveTogether )
	{
		pDockThumb = FindFrameByWnd( pDockThumb->dockOpt.hwndRight );

		PositionThumb( pDockThumb, (short)( nNewX + nWidth ), (short)nNewY );
	}
}



static void GetBorderSize(HWND hwnd,RECT *rect)
{
	RECT wr,cr;
	POINT pt1,pt2;
	//  RECT r={0};
	//  *rect=r;
	//  return;
	GetWindowRect(hwnd,&wr);
	GetClientRect(hwnd,&cr);
	pt1.y=cr.top;pt1.x=cr.left;
	pt2.y=cr.bottom;pt2.x=cr.right;

	ClientToScreen(hwnd,&pt1);
	ClientToScreen(hwnd,&pt2);

	cr.top=pt1.y;cr.left=pt1.x;
	cr.bottom=pt2.y;cr.right=pt2.x;

	rect->top=cr.top-wr.top;
	rect->left=cr.left-wr.left;
	rect->right=wr.right-cr.right;
	rect->bottom=wr.bottom-cr.bottom;
	//if (rect->top+rect->bottom>10){rect->top=rect->bottom=2;};
	//if (rect->left+rect->right>10){rect->top=rect->bottom=2;};

};

static char __inline *AS(char *str,const char *setting,char *addstr)
{
	if(str!=NULL) {
		strcpy(str,setting);
		strcat(str,addstr);
	}
	return str;
}

static int DBLoadFrameSettingsAtPos(int pos,int Frameid)
{
	char sadd[15];
	char buf[255];
	//	char *oldtb;

	_itoa(pos,sadd,10);

	//DBWriteContactSettingString(0,CLUIFrameModule,strcat("Name",sadd),Frames[Frameid].name);
	//boolean
	g_pfwFrames[Frameid].collapsed=db_get_b(0,CLUIFrameModule,AS(buf,"Collapse",sadd),g_pfwFrames[Frameid].collapsed);

	g_pfwFrames[Frameid].Locked					=db_get_b(0,CLUIFrameModule,AS(buf,"Locked",sadd),g_pfwFrames[Frameid].Locked);
	g_pfwFrames[Frameid].visible					=db_get_b(0,CLUIFrameModule,AS(buf,"Visible",sadd),g_pfwFrames[Frameid].visible);
	g_pfwFrames[Frameid].TitleBar.ShowTitleBar	=db_get_b(0,CLUIFrameModule,AS(buf,"TBVisile",sadd),g_pfwFrames[Frameid].TitleBar.ShowTitleBar);

	g_pfwFrames[Frameid].height					=db_get_w(0,CLUIFrameModule,AS(buf,"Height",sadd),g_pfwFrames[Frameid].height);
	g_pfwFrames[Frameid].HeightWhenCollapsed		=db_get_w(0,CLUIFrameModule,AS(buf,"HeightCollapsed",sadd),0);
	g_pfwFrames[Frameid].align					=db_get_w(0,CLUIFrameModule,AS(buf,"Align",sadd),g_pfwFrames[Frameid].align);

	g_pfwFrames[Frameid].FloatingPos.x		=DBGetContactSettingRangedWord(0,CLUIFrameModule,AS(buf,"FloatX",sadd),100,0,2048);
	g_pfwFrames[Frameid].FloatingPos.y		=DBGetContactSettingRangedWord(0,CLUIFrameModule,AS(buf,"FloatY",sadd),100,0,2048);
	g_pfwFrames[Frameid].FloatingSize.x		=DBGetContactSettingRangedWord(0,CLUIFrameModule,AS(buf,"FloatW",sadd),100,0,2048);
	g_pfwFrames[Frameid].FloatingSize.y		=DBGetContactSettingRangedWord(0,CLUIFrameModule,AS(buf,"FloatH",sadd),100,0,2048);

	g_pfwFrames[Frameid].floating			=db_get_b(0,CLUIFrameModule,AS(buf,"Floating",sadd),0);
	g_pfwFrames[Frameid].order				=db_get_w(0,CLUIFrameModule,AS(buf,"Order",sadd),0);

	g_pfwFrames[Frameid].UseBorder			=db_get_b(0,CLUIFrameModule,AS(buf,"UseBorder",sadd),g_pfwFrames[Frameid].UseBorder);

	return 0;
}

static int DBStoreFrameSettingsAtPos(int pos,int Frameid)
{
	char sadd[16];
	char buf[255];

	_itoa(pos,sadd,10);

	db_set_ws(0,CLUIFrameModule,AS(buf,"Name",sadd),g_pfwFrames[Frameid].Name);
	//boolean
	db_set_b(0,CLUIFrameModule,AS(buf,"Collapse",sadd),(BYTE)btoint(g_pfwFrames[Frameid].collapsed));
	db_set_b(0,CLUIFrameModule,AS(buf,"Locked",sadd),(BYTE)btoint(g_pfwFrames[Frameid].Locked));
	db_set_b(0,CLUIFrameModule,AS(buf,"Visible",sadd),(BYTE)btoint(g_pfwFrames[Frameid].visible));
	db_set_b(0,CLUIFrameModule,AS(buf,"TBVisile",sadd),(BYTE)btoint(g_pfwFrames[Frameid].TitleBar.ShowTitleBar));

	db_set_w(0,CLUIFrameModule,AS(buf,"Height",sadd),(WORD)g_pfwFrames[Frameid].height);
	db_set_w(0,CLUIFrameModule,AS(buf,"HeightCollapsed",sadd),(WORD)g_pfwFrames[Frameid].HeightWhenCollapsed);
	db_set_w(0,CLUIFrameModule,AS(buf,"Align",sadd),(WORD)g_pfwFrames[Frameid].align);
	//FloatingPos
	db_set_w(0,CLUIFrameModule,AS(buf,"FloatX",sadd),(WORD)g_pfwFrames[Frameid].FloatingPos.x);
	db_set_w(0,CLUIFrameModule,AS(buf,"FloatY",sadd),(WORD)g_pfwFrames[Frameid].FloatingPos.y);
	db_set_w(0,CLUIFrameModule,AS(buf,"FloatW",sadd),(WORD)g_pfwFrames[Frameid].FloatingSize.x);
	db_set_w(0,CLUIFrameModule,AS(buf,"FloatH",sadd),(WORD)g_pfwFrames[Frameid].FloatingSize.y);

	db_set_b(0,CLUIFrameModule,AS(buf,"Floating",sadd),(BYTE)btoint(g_pfwFrames[Frameid].floating));
	db_set_b(0,CLUIFrameModule,AS(buf,"UseBorder",sadd),(BYTE)btoint(g_pfwFrames[Frameid].UseBorder));
	db_set_w(0,CLUIFrameModule,AS(buf,"Order",sadd),(WORD)g_pfwFrames[Frameid].order);
	return 0;
}

static int LocateStorePosition(int Frameid,int maxstored)
{

    if(g_pfwFrames[Frameid].Name==NULL)
        return -1;
    char settingname[255];
	for ( int i=0;i<maxstored;i++)
    {

        mir_snprintf(settingname,SIZEOF(settingname),"Name%d",i);
        DBVARIANT dbv={0};
        if ( DBGetContactSettingTString( NULL, CLUIFrameModule, settingname, &dbv ))
            continue;

		if ( lstrcmpi( dbv.ptszVal, g_pfwFrames[Frameid].Name ) ==0 )
        {
			db_free( &dbv );
			return i;
		}
        db_free( &dbv );
	}
	return -1;
}

static int CLUIFramesLoadFrameSettings(int Frameid)
{
	int storpos,maxstored;

	if (_fCluiFramesModuleNotStarted) return -1;

	if(Frameid<0||Frameid>=g_nFramesCount) return -1;

	maxstored=db_get_w(0,CLUIFrameModule,"StoredFrames",-1);
	if(maxstored==-1) return 0;

	storpos=LocateStorePosition(Frameid,maxstored);
	if(storpos==-1) return 0;

	DBLoadFrameSettingsAtPos(storpos,Frameid);
	return 0;
}

static int CLUIFramesStoreFrameSettings(int Frameid)
{
	int maxstored,storpos;

	if (_fCluiFramesModuleNotStarted) return -1;

	if(Frameid<0||Frameid>=g_nFramesCount) return -1;

	maxstored=db_get_w(0,CLUIFrameModule,"StoredFrames",-1);
	if(maxstored==-1) maxstored=0;

	storpos=LocateStorePosition(Frameid,maxstored);
	if(storpos==-1) {storpos=maxstored; maxstored++;}

	DBStoreFrameSettingsAtPos(storpos,Frameid);
	db_set_w(0,CLUIFrameModule,"StoredFrames",(WORD)maxstored);

	return 0;
}

static int CLUIFramesStoreAllFrames()
{
	int i;
	if (_fCluiFramesModuleNotStarted) return -1;
	for(i=0;i<g_nFramesCount;i++)
		CLUIFramesStoreFrameSettings(i);
	return 0;
}

static int CLUIFramesGetalClientFrame(void)
{
	int i;
	if (_fCluiFramesModuleNotStarted) return -1;

	if ( _nClientFrameId != eUnknownId ) {
		/* this value could become invalid if RemoveItemFromList was called,
		* so we double-check */
		if (_nClientFrameId<g_nFramesCount) {
			if(g_pfwFrames[_nClientFrameId].align==alClient) {
				return _nClientFrameId;
			}
		}
	}

	for(i=0;i<g_nFramesCount;i++)
		if(g_pfwFrames[i].align==alClient) {
			_nClientFrameId=i;
			return i;
		}
		return -1;
}

static HMENU CLUIFramesCreateMenuForFrame(int frameid,int root,int popuppos,HGENMENU (*pfnAdd)(CLISTMENUITEM*))
{
	//TMO_MenuItem tmi;
	HGENMENU menuid;
	int framepos=id2pos(frameid);

	if (_fCluiFramesModuleNotStarted)
		return NULL;

	CLISTMENUITEM mi = { 0 };
	mi.cbSize=sizeof(mi);
	mi.flags=CMIF_ICONFROMICOLIB;
	mi.pszPopupName=(char *)root;
	mi.popupPosition=frameid;
	mi.position=popuppos++;
	mi.pszName=LPGEN("&Visible");
	mi.flags=CMIF_CHILDPOPUP|CMIF_CHECKED;
	mi.pszContactOwner=(char *)0;
	mi.pszService=MS_CLIST_FRAMES_SHFRAME;
	menuid = pfnAdd(&mi);
	if(frameid==-1) _hmiVisible=menuid;
	else g_pfwFrames[framepos].MenuHandles.MIVisible=menuid;

	popuppos+=100000;

	mi.pszPopupName=(char *)root;
	mi.popupPosition=frameid;
	mi.position=popuppos++;
	mi.pszName=LPGEN("&Show title");
	mi.flags=CMIF_CHILDPOPUP|CMIF_CHECKED;
	mi.pszService=MS_CLIST_FRAMES_SHFRAMETITLEBAR;
	mi.pszContactOwner=(char *)0;
	menuid=pfnAdd(&mi);
	if(frameid==-1) _hmiTBVisible=menuid;
	else g_pfwFrames[framepos].MenuHandles.MITBVisible=menuid;

	mi.pszPopupName=(char *)root;
	mi.popupPosition=frameid;
	mi.position=popuppos++;
	mi.pszName=LPGEN("&Locked");
	mi.flags=CMIF_CHILDPOPUP|CMIF_CHECKED;
	mi.pszService=MS_CLIST_FRAMES_ULFRAME;
	mi.pszContactOwner=(char *)0;
	menuid=pfnAdd(&mi);
	if(frameid==-1) _hmiLock=menuid;
	else g_pfwFrames[framepos].MenuHandles.MILock=menuid;

	mi.pszPopupName=(char *)root;
	mi.popupPosition=frameid;
	mi.position=popuppos++;
	mi.pszName=LPGEN("&Expanded");
	mi.flags=CMIF_CHILDPOPUP|CMIF_CHECKED;
	mi.pszService=MS_CLIST_FRAMES_UCOLLFRAME;
	mi.pszContactOwner=(char *)0;
	menuid=pfnAdd(&mi);
	if(frameid==-1) _hmiColl=menuid;
	else g_pfwFrames[framepos].MenuHandles.MIColl=menuid;

	//floating
	mi.pszPopupName=(char *)root;
	mi.popupPosition=frameid;
	mi.position=popuppos++;
	mi.pszName=LPGEN("&Floating Mode");
	mi.flags=CMIF_CHILDPOPUP;
	mi.pszService="Set_Floating";
	mi.pszContactOwner=(char *)0;
	menuid=pfnAdd(&mi);
	if(frameid==-1) _hmiFloating=menuid;
	else g_pfwFrames[framepos].MenuHandles.MIFloating=menuid;

	mi.pszPopupName=(char *)root;
	mi.popupPosition=frameid;
	mi.position=popuppos++;
	mi.pszName=LPGEN("&Border");
	mi.flags=CMIF_CHILDPOPUP|CMIF_CHECKED;
	mi.pszService=MS_CLIST_FRAMES_SETUNBORDER;
	mi.pszContactOwner=(char *)0;
	menuid=pfnAdd(&mi);
	if(frameid==-1) _hmiBorder=menuid;
	else g_pfwFrames[framepos].MenuHandles.MIBorder=menuid;

	popuppos+=100000;

	{
		//alignment root
		mi.pszPopupName=(char *)root;
		mi.popupPosition=frameid;
		mi.position=popuppos++;
		mi.pszName=LPGEN("&Align");
		mi.flags=CMIF_CHILDPOPUP|CMIF_ROOTPOPUP;
		mi.pszService="";
		mi.pszContactOwner=(char *)0;
		menuid=pfnAdd(&mi);
		if(frameid==-1) _hmiAlignRoot=menuid;
		else g_pfwFrames[framepos].MenuHandles.MIAlignRoot=menuid;

		mi.flags=CMIF_CHILDPOPUP;
		//align top
		mi.pszPopupName=(char *)menuid;
		mi.popupPosition=frameid;
		mi.position=popuppos++;
		mi.pszName=LPGEN("&Top");
		mi.pszService=CLUIFRAMESSETALIGNALTOP;
		mi.pszContactOwner=(char *)alTop;
		menuid=pfnAdd(&mi);
		if(frameid==-1) _hmiAlignTop=menuid;
		else g_pfwFrames[framepos].MenuHandles.MIAlignTop=menuid;


		//align client
		mi.position=popuppos++;
		mi.pszName=LPGEN("&Client");
		mi.pszService=CLUIFRAMESSETALIGNALCLIENT;
		mi.pszContactOwner=(char *)alClient;
		menuid=pfnAdd(&mi);
		if(frameid==-1) _hmiAlignClient=menuid;
		else g_pfwFrames[framepos].MenuHandles.MIAlignClient=menuid;

		//align bottom
		mi.position=popuppos++;
		mi.pszName=LPGEN("&Bottom");
		mi.pszService=CLUIFRAMESSETALIGNALBOTTOM;
		mi.pszContactOwner=(char *)alBottom;
		menuid=pfnAdd(&mi);
		if(frameid==-1) _hmiAlignBottom=menuid;
		else g_pfwFrames[framepos].MenuHandles.MIAlignBottom=menuid;

	}

	{	//position
		//position root
		mi.pszPopupName=(char *)root;
		mi.popupPosition=frameid;
		mi.position=popuppos++;
		mi.pszName=LPGEN("&Position");
		mi.flags=CMIF_CHILDPOPUP|CMIF_ROOTPOPUP;
		mi.pszService="";
		mi.pszContactOwner=(char *)0;
		menuid=pfnAdd(&mi);
		if(frameid==-1) _hmiPosRoot=menuid;
		else g_pfwFrames[framepos].MenuHandles.MIPosRoot=menuid;
		//??????
		mi.pszPopupName=(char *)menuid;
		mi.popupPosition=frameid;
		mi.position=popuppos++;
		mi.pszName=LPGEN("&Up");
		mi.flags=CMIF_CHILDPOPUP;
		mi.pszService=CLUIFRAMESMOVEUP;
		mi.pszContactOwner=(char *)1;
		menuid=pfnAdd(&mi);
		if(frameid==-1) _hmiPosUp=menuid;
		else g_pfwFrames[framepos].MenuHandles.MIPosUp=menuid;

		mi.popupPosition=frameid;
		mi.position=popuppos++;
		mi.pszName=LPGEN("&Down");
		mi.flags=CMIF_CHILDPOPUP;
		mi.pszService=CLUIFRAMESMOVEDOWN;
		mi.pszContactOwner=(char *)-1;
		menuid=pfnAdd(&mi);
		if(frameid==-1) _hmiPosDown=menuid;
		else g_pfwFrames[framepos].MenuHandles.MIPosDown=menuid;

	}

	return 0;
}

static int ModifyMItem(WPARAM wParam,LPARAM lParam)
{
	if ( (int) wParam == -1 ) return 0;	   // FIXME

	return ModifyMenuItemProxy(wParam,lParam);
};


static int CLUIFramesModifyContextMenuForFrame(WPARAM wParam,LPARAM lParam)
{
	int pos;
	CLISTMENUITEM mi;
	/* HOOK */
	if (MirandaExiting()) return 0;
	if (_fCluiFramesModuleNotStarted) return -1;
	pos=id2pos(wParam);
	if(pos>=0&&pos<g_nFramesCount) {
		memset(&mi,0,sizeof(mi));
		mi.cbSize=sizeof(mi);
		mi.flags=CMIM_FLAGS|CMIM_NAME|CMIF_CHILDPOPUP|CMIF_TCHAR;
		if(g_pfwFrames[pos].visible) mi.flags|=CMIF_CHECKED;
		mi.ptszName=g_pfwFrames[pos].TitleBar.tbname ? g_pfwFrames[pos].TitleBar.tbname : g_pfwFrames[pos].Name;
		ModifyMItem((WPARAM)_hmiVisible,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].Locked) mi.flags|=CMIF_CHECKED;
		ModifyMItem((WPARAM)_hmiLock,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].TitleBar.ShowTitleBar) mi.flags|=CMIF_CHECKED;
		ModifyMItem((WPARAM)_hmiTBVisible,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].floating) mi.flags|=CMIF_CHECKED;
		ModifyMItem((WPARAM)_hmiFloating,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if ( g_CluiData.fLayered ) mi.flags|=CMIF_GRAYED;
		else if ((g_pfwFrames[pos].UseBorder)) mi.flags|=CMIF_CHECKED;
		ModifyMItem((WPARAM)_hmiBorder,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].align&alTop) mi.flags|=CMIF_CHECKED;
		ModifyMItem((WPARAM)_hmiAlignTop,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].align&alClient) mi.flags|=CMIF_CHECKED;
		ModifyMItem((WPARAM)_hmiAlignClient,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].align&alBottom) mi.flags|=CMIF_CHECKED;
		ModifyMItem((WPARAM)_hmiAlignBottom,(LPARAM)&mi);


		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].collapsed) mi.flags|=CMIF_CHECKED;
		if ((!g_pfwFrames[pos].visible)||(g_pfwFrames[pos].Locked)||(pos==CLUIFramesGetalClientFrame())) mi.flags|=CMIF_GRAYED;
		ModifyMItem((WPARAM)_hmiColl,(LPARAM)&mi);
	}
	return 0;
}

static int CLUIFramesModifyMainMenuItems(WPARAM wParam,LPARAM lParam)
{
	//hiword(wParam)=frameid,loword(wParam)=flag
	int pos;
	CLISTMENUITEM mi;
	//TMO_MenuItem tmi;

	if (_fCluiFramesModuleNotStarted) return -1;


	pos=id2pos(wParam);

	if (pos>=0&&pos<g_nFramesCount) {
		memset(&mi,0,sizeof(mi));
		mi.cbSize=sizeof(mi);
		mi.flags=CMIM_FLAGS|CMIM_NAME|CMIF_CHILDPOPUP|CMIF_TCHAR;
		if(g_pfwFrames[pos].visible) mi.flags|=CMIF_CHECKED;
		mi.ptszName=g_pfwFrames[pos].TitleBar.tbname ? g_pfwFrames[pos].TitleBar.tbname : g_pfwFrames[pos].Name;
		CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_pfwFrames[pos].MenuHandles.MIVisible,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].Locked) mi.flags|=CMIF_CHECKED;
		CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_pfwFrames[pos].MenuHandles.MILock,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].TitleBar.ShowTitleBar) mi.flags|=CMIF_CHECKED;
		CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_pfwFrames[pos].MenuHandles.MITBVisible,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].floating) mi.flags|=CMIF_CHECKED;
		CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_pfwFrames[pos].MenuHandles.MIFloating,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;

		if ( g_CluiData.fLayered ) mi.flags|=CMIF_GRAYED;
		else if ((g_pfwFrames[pos].UseBorder)) mi.flags|=CMIF_CHECKED;
		CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_pfwFrames[pos].MenuHandles.MIBorder,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP|((g_pfwFrames[pos].align&alClient)?CMIF_GRAYED:0);
		if(g_pfwFrames[pos].align&alTop) mi.flags|=CMIF_CHECKED;
		CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_pfwFrames[pos].MenuHandles.MIAlignTop,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].align&alClient) mi.flags|=CMIF_CHECKED;
		CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_pfwFrames[pos].MenuHandles.MIAlignClient,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP|((g_pfwFrames[pos].align&alClient)?CMIF_GRAYED:0);
		if(g_pfwFrames[pos].align&alBottom) mi.flags|=CMIF_CHECKED;
		CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_pfwFrames[pos].MenuHandles.MIAlignBottom,(LPARAM)&mi);

		/*
		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP|((Frames[pos].align&alClient)?CMIF_GRAYED:0);
		if(Frames[pos].align&alTop) mi.flags|=CMIF_CHECKED;
		ModifyMItem((WPARAM)contMIAlignTop,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP|CMIF_GRAYED;
		if(Frames[pos].align&alClient) mi.flags|=CMIF_CHECKED;
		ModifyMItem((WPARAM)contMIAlignClient,(LPARAM)&mi);

		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP|((Frames[pos].align&alClient)?CMIF_GRAYED:0);
		if(Frames[pos].align&alBottom) mi.flags|=CMIF_CHECKED;
		ModifyMItem((WPARAM)contMIAlignBottom,(LPARAM)&mi);

		*/



		mi.flags=CMIM_FLAGS|CMIF_CHILDPOPUP;
		if(g_pfwFrames[pos].collapsed) mi.flags|=CMIF_CHECKED;
		if ((!g_pfwFrames[pos].visible)||g_pfwFrames[pos].Locked||(pos==CLUIFramesGetalClientFrame())) mi.flags|=CMIF_GRAYED;
		CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_pfwFrames[pos].MenuHandles.MIColl,(LPARAM)&mi);
	}

	return 0;
}


static INT_PTR _us_DoGetFrameOptions(WPARAM wParam,LPARAM lParam)
{
	int pos;
	INT_PTR retval;
	BOOL bUnicodeText=(LOWORD(wParam) & FO_UNICODETEXT)!=0;
	wParam=MAKEWPARAM((LOWORD(wParam)) & ~FO_UNICODETEXT, HIWORD(wParam));

	if (_fCluiFramesModuleNotStarted) return -1;


	pos=id2pos(HIWORD(wParam));
	if(pos<0||pos>=g_nFramesCount) {

		return -1;
	}

	switch(LOWORD(wParam))
	{
	case FO_FLAGS:
		retval=0;
		if(g_pfwFrames[pos].visible) retval|=F_VISIBLE;
		if (!g_pfwFrames[pos].collapsed) retval|=F_UNCOLLAPSED;
		if(g_pfwFrames[pos].Locked) retval|=F_LOCKED;
		if(g_pfwFrames[pos].TitleBar.ShowTitleBar) retval|=F_SHOWTB;
		if(g_pfwFrames[pos].TitleBar.ShowTitleBarTip) retval|=F_SHOWTBTIP;
		if (!g_CluiData.fLayered)
		{
			if (!(GetWindowLongPtr(g_pfwFrames[pos].hWnd,GWL_STYLE)&WS_BORDER)) retval|=F_NOBORDER;
		}
		else
			if (!g_pfwFrames[pos].UseBorder) retval|=F_NOBORDER;


		break;

	case FO_NAME:
		if (bUnicodeText)
			retval=(INT_PTR)g_pfwFrames[pos].Name;
		else
			retval=(INT_PTR)g_pfwFrames[pos].szName;
		break;

	case FO_TBNAME:
		if (bUnicodeText)
			retval=(INT_PTR)g_pfwFrames[pos].TitleBar.tbname;
		else
			retval=(INT_PTR)g_pfwFrames[pos].TitleBar.sztbname;
		break;

	case FO_TBTIPNAME:
		if (bUnicodeText)
			retval=(INT_PTR)g_pfwFrames[pos].TitleBar.tooltip;
		else
			retval=(INT_PTR)g_pfwFrames[pos].TitleBar.sztooltip;
		break;

	case FO_TBSTYLE:
		retval=GetWindowLongPtr(g_pfwFrames[pos].TitleBar.hwnd,GWL_STYLE);
		break;

	case FO_TBEXSTYLE:
		retval=GetWindowLongPtr(g_pfwFrames[pos].TitleBar.hwnd,GWL_EXSTYLE);
		break;

	case FO_ICON:
		retval=(INT_PTR)g_pfwFrames[pos].TitleBar.hicon;
		break;

	case FO_HEIGHT:
		retval=(INT_PTR)g_pfwFrames[pos].height;
		break;

	case FO_ALIGN:
		retval=(INT_PTR)g_pfwFrames[pos].align;
		break;
	case FO_FLOATING:
		retval=(INT_PTR)g_pfwFrames[pos].floating;
		break;
	default:
		retval=-1;
		break;
	}

	return retval;
}

static int UpdateTBToolTip(int framepos)
{
	{
		TOOLINFO ti;

		ZeroMemory(&ti,sizeof(ti));
		ti.cbSize=sizeof(ti);
		ti.lpszText=g_pfwFrames[framepos].TitleBar.tooltip;
		ti.hinst=g_hInst;
		ti.uFlags=TTF_IDISHWND|TTF_SUBCLASS ;
		ti.uId=(UINT_PTR)g_pfwFrames[framepos].TitleBar.hwnd;

		return(SendMessage(g_pfwFrames[framepos].TitleBar.hwndTip,TTM_UPDATETIPTEXT ,(WPARAM)0,(LPARAM)&ti));
	}

};
//hiword(wParam)=frameid,loword(wParam)=flag
static int _us_DoSetFrameOptions(WPARAM wParam,LPARAM lParam)
{
	int pos;
	int retval; // value to be returned
	BOOL bUnicodeText=(LOWORD(wParam) & FO_UNICODETEXT)!=0;
	wParam=MAKEWPARAM((LOWORD(wParam))& ~FO_UNICODETEXT, HIWORD(wParam));
	if (_fCluiFramesModuleNotStarted) return -1;


	pos=id2pos(HIWORD(wParam));
	if(pos<0||pos>=g_nFramesCount) {

		return -1;
	}

	switch(LOWORD(wParam))
	{
	case FO_FLAGS:{
		int flag=lParam;
		int style;

		g_pfwFrames[pos].dwFlags=flag;
		g_pfwFrames[pos].visible=FALSE;
		if(flag&F_VISIBLE) g_pfwFrames[pos].visible=TRUE;

		g_pfwFrames[pos].collapsed=TRUE;
		if(flag&F_UNCOLLAPSED) g_pfwFrames[pos].collapsed=FALSE;

		g_pfwFrames[pos].Locked=FALSE;
		if(flag&F_LOCKED) g_pfwFrames[pos].Locked=TRUE;

		g_pfwFrames[pos].UseBorder=TRUE;
		if(flag&F_NOBORDER) g_pfwFrames[pos].UseBorder=FALSE;

		g_pfwFrames[pos].TitleBar.ShowTitleBar=FALSE;
		if(flag&F_SHOWTB) g_pfwFrames[pos].TitleBar.ShowTitleBar=TRUE;

		g_pfwFrames[pos].TitleBar.ShowTitleBarTip=FALSE;
		if(flag&F_SHOWTBTIP) g_pfwFrames[pos].TitleBar.ShowTitleBarTip=TRUE;

		SendMessageA(g_pfwFrames[pos].TitleBar.hwndTip,TTM_ACTIVATE,(WPARAM)g_pfwFrames[pos].TitleBar.ShowTitleBarTip,0);

		style=(int)GetWindowLongPtr(g_pfwFrames[pos].hWnd,GWL_STYLE);
		style&=(~WS_BORDER);

		if ( !(flag&F_NOBORDER ) && !g_CluiData.fLayered ) style|=WS_BORDER;

		SetWindowLongPtr(g_pfwFrames[pos].hWnd,GWL_STYLE,(long)style);
		SetWindowLongPtr(g_pfwFrames[pos].TitleBar.hwnd,GWL_STYLE,(long)style& ~(WS_VSCROLL | WS_HSCROLL));

		CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
		SetWindowPos(g_pfwFrames[pos].TitleBar.hwnd,0,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED|SWP_NOACTIVATE);
		return 0;
				  }

	case FO_NAME:
		if(lParam==(LPARAM)NULL) { return -1;}
		if(g_pfwFrames[pos].Name!=NULL) mir_free(g_pfwFrames[pos].Name);
		if(g_pfwFrames[pos].szName!=NULL) mir_free(g_pfwFrames[pos].szName);
		if (bUnicodeText)
		{
			g_pfwFrames[pos].Name=mir_tstrdup((LPTSTR)lParam);
			g_pfwFrames[pos].szName=mir_t2a((LPTSTR)lParam);
		}
		else
		{
			g_pfwFrames[pos].szName=mir_strdup((char*)lParam);
			g_pfwFrames[pos].Name=mir_a2t((char *)lParam);
		}
		return 0;

	case FO_TBNAME:
		if(lParam==(LPARAM)NULL) { return(-1);}

		if(g_pfwFrames[pos].TitleBar.tbname!=NULL) mir_free(g_pfwFrames[pos].TitleBar.tbname);
		if(g_pfwFrames[pos].TitleBar.sztbname!=NULL) mir_free(g_pfwFrames[pos].TitleBar.sztbname);
		if (bUnicodeText)
		{
			g_pfwFrames[pos].TitleBar.tbname=mir_tstrdup((LPTSTR)lParam);
			g_pfwFrames[pos].TitleBar.sztbname=mir_t2a((LPTSTR)lParam);
		}
		else
		{
			g_pfwFrames[pos].TitleBar.sztbname=mir_strdup((char*)lParam);
			g_pfwFrames[pos].TitleBar.tbname=mir_a2t((char*)lParam);
		}

		if (g_pfwFrames[pos].floating&&(g_pfwFrames[pos].TitleBar.tbname!=NULL)){SetWindowText(g_pfwFrames[pos].ContainerWnd,g_pfwFrames[pos].TitleBar.tbname);};
		return 0;

	case FO_TBTIPNAME:
		if(lParam==(LPARAM)NULL) { return(-1);}
		if(g_pfwFrames[pos].TitleBar.tooltip!=NULL) mir_free_and_nill(g_pfwFrames[pos].TitleBar.tooltip);
		if(g_pfwFrames[pos].TitleBar.sztooltip!=NULL) mir_free_and_nill(g_pfwFrames[pos].TitleBar.sztooltip);
		if (bUnicodeText)
		{
			g_pfwFrames[pos].TitleBar.tooltip=mir_tstrdup((LPTSTR)lParam);
			g_pfwFrames[pos].TitleBar.sztooltip=mir_t2a((LPTSTR)lParam);
		}
		else
		{
			g_pfwFrames[pos].TitleBar.sztooltip=mir_strdup((char*)lParam);
			g_pfwFrames[pos].TitleBar.tooltip=mir_a2t((char*)lParam);
		}
		UpdateTBToolTip(pos);

		return 0;

	case FO_TBSTYLE:
		SetWindowLongPtr(g_pfwFrames[pos].TitleBar.hwnd,GWL_STYLE,lParam& ~(WS_VSCROLL | WS_HSCROLL));

		return 0;

	case FO_TBEXSTYLE:
		SetWindowLongPtr(g_pfwFrames[pos].TitleBar.hwnd,GWL_EXSTYLE,lParam);

		return 0;

	case FO_ICON:
		g_pfwFrames[pos].TitleBar.hicon=(HICON)lParam;

		return 0;

	case FO_HEIGHT:
		if(lParam<0) { return -1;}

		if (g_pfwFrames[pos].collapsed)
		{
			int oldHeight=g_pfwFrames[pos].height;
			retval=g_pfwFrames[pos].height;
			g_pfwFrames[pos].height=lParam;
			if (!CLUIFramesFitInSize()) g_pfwFrames[pos].height=retval;
			retval=g_pfwFrames[pos].height;
			if (g_pfwFrames[pos].height != oldHeight)
				CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
		}
		else
		{
			retval=g_pfwFrames[pos].HeightWhenCollapsed;
			g_pfwFrames[pos].HeightWhenCollapsed=lParam;
			if (!CLUIFramesFitInSize()) g_pfwFrames[pos].HeightWhenCollapsed=retval;
			retval=g_pfwFrames[pos].HeightWhenCollapsed;

		}
		return retval;

	case FO_FLOATING:
		if(lParam<0) { return -1;}

		{
			int id=g_pfwFrames[pos].id;
			g_pfwFrames[pos].floating=!(lParam);


			CLUIFrames_SetFrameFloat(id,1);//lparam=1 use stored width and height
			return(wParam);
		}

	case FO_ALIGN:
		if (!(lParam&alTop||lParam&alBottom||lParam&alClient))
		{
			TRACE("Wrong align option \r\n");
			return (-1);
		};

		if ((lParam&alClient)&&(CLUIFramesGetalClientFrame()>=0)) {	//only one alClient frame possible
			_nClientFrameId = eUnknownId;//recalc it

			return -1;
		}
		g_pfwFrames[pos].align=lParam;


		return(0);
	}

	CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
	return -1;
}

//wparam=lparam=0
static int _us_DoShowAllFrames(WPARAM wParam,LPARAM lParam)
{
	int i;

	if (_fCluiFramesModuleNotStarted) return -1;

	for(i=0;i<g_nFramesCount;i++)
		g_pfwFrames[i].visible=TRUE;
	CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
	return 0;
}

//wparam=lparam=0
static int _us_DoShowTitles(WPARAM wParam,LPARAM lParam)
{
	int i;

	if (_fCluiFramesModuleNotStarted) return -1;

	for(i=0;i<g_nFramesCount;i++)
		g_pfwFrames[i].TitleBar.ShowTitleBar=TRUE;
	CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
	return 0;
}

//wparam=lparam=0
static int _us_DoHideTitles(WPARAM wParam,LPARAM lParam)
{
	int i;

	if (_fCluiFramesModuleNotStarted) return -1;

	for(i=0;i<g_nFramesCount;i++)
		g_pfwFrames[i].TitleBar.ShowTitleBar=FALSE;
	CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
	return 0;
}

//wparam=frameid
static int _us_DoShowHideFrame(WPARAM wParam,LPARAM lParam)
{
	int pos;

	if (_fCluiFramesModuleNotStarted) return -1;

	if (wParam == 0) {
		pos =  lParam;
	} else {
    	pos=id2pos(wParam);
	}
	if(pos>=0&&(int)pos<g_nFramesCount)
	{
		g_pfwFrames[pos].visible=!g_pfwFrames[pos].visible;
		if (g_pfwFrames[pos].OwnerWindow!=(HWND)-2)
		{
			if (g_pfwFrames[pos].OwnerWindow)
				CLUI_ShowWindowMod(g_pfwFrames[pos].OwnerWindow,(g_pfwFrames[pos].visible&& g_pfwFrames[pos].collapsed && IsWindowVisible(pcli->hwndContactList))?SW_SHOW/*NOACTIVATE*/:SW_HIDE);
			else if (g_pfwFrames[pos].visible)
			{
				g_pfwFrames[pos].OwnerWindow=CreateSubContainerWindow(pcli->hwndContactList,g_pfwFrames[pos].FloatingPos.x,g_pfwFrames[pos].FloatingPos.y,10,10);
				SetParent(g_pfwFrames[pos].hWnd,g_pfwFrames[pos].OwnerWindow);
				CLUI_ShowWindowMod(g_pfwFrames[pos].OwnerWindow,(g_pfwFrames[pos].visible && g_pfwFrames[pos].collapsed && IsWindowVisible(pcli->hwndContactList))?SW_SHOW/*NOACTIVATE*/:SW_HIDE);
			}
		}
		if (g_pfwFrames[pos].floating){CLUIFrameResizeFloatingFrame(pos);};

		if (!g_pfwFrames[pos].floating) CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
	}
	return 0;
}

//wparam=frameid
static int _us_DoShowHideFrameTitle(WPARAM wParam,LPARAM lParam)
{
	int pos;

	if (_fCluiFramesModuleNotStarted) return -1;

	if (wParam == 0) {
		pos =  lParam;
	} else {
    	pos=id2pos(wParam);
	}
	if(pos>=0&&(int)pos<g_nFramesCount)
		g_pfwFrames[pos].TitleBar.ShowTitleBar=!g_pfwFrames[pos].TitleBar.ShowTitleBar;
	//if (Frames[pos].height>



	CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);


	return 0;
}

//wparam=frameid
//lparam=-1 up ,1 down
static int _us_DoMoveFrame(WPARAM wParam,LPARAM lParam)
{
	int pos,i,curpos,curalign,v,tmpval;

	if (_fCluiFramesModuleNotStarted) return -1;

	pos=id2pos(wParam);
	if(pos>=0&&(int)pos<g_nFramesCount)	{
		SortData *sd;
		curpos=g_pfwFrames[pos].order;
		curalign=g_pfwFrames[pos].align;
		v=0;
		sd=(SortData*)malloc(sizeof(SortData)*g_nFramesCount);
		memset(sd,0,sizeof(SortData)*g_nFramesCount);
		for (i=0;i<g_nFramesCount;i++)
		{
			if (g_pfwFrames[i].floating||(!g_pfwFrames[i].visible)||(g_pfwFrames[i].align!=curalign)){continue;};

			sd[v].order=g_pfwFrames[i].order;
			sd[v].realpos=i;
			v++;
		};
		if (v==0){return(0);};
		qsort(sd,v,sizeof(SortData),sortfunc);
		for (i=0;i<v;i++)
			g_pfwFrames[sd[i].realpos].order=i+1; //to be sure that order is incremental
		for (i=0;i<v;i++)
		{
			if (sd[i].realpos==pos)
			{
				if (lParam==-1)
				{
					if (i>=v-1) break;
					tmpval=g_pfwFrames[sd[i+1].realpos].order;
					g_pfwFrames[sd[i+1].realpos].order=g_pfwFrames[pos].order;
					g_pfwFrames[pos].order=tmpval;
					break;
				};
				if (lParam==+1)
				{
					if (i<1) break;
					tmpval=g_pfwFrames[sd[i-1].realpos].order;
					g_pfwFrames[sd[i-1].realpos].order=g_pfwFrames[pos].order;
					g_pfwFrames[pos].order=tmpval;
					break;
				};


			};
		};

		if (sd!=NULL){free(sd);};
		CLUIFramesStoreFrameSettings(pos);
		CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,0);

	}

	return(0);
};



static int _us_DoMoveFrameUp(WPARAM wParam,LPARAM lParam)
{
	return CLUIFrames_MoveFrame(wParam,(LPARAM)+1);
}
static int _us_DoMoveFrameDown(WPARAM wParam,LPARAM lParam)
{
	return CLUIFrames_MoveFrame(wParam,(LPARAM)-1);
}
//wparam=frameid
//lparam=alignment
static int _us_DoSetFrameAlign(WPARAM wParam,LPARAM lParam)
{
	if (_fCluiFramesModuleNotStarted) return -1;

	CLUIFrames_SetFrameOptions(MAKEWPARAM(FO_ALIGN,wParam),lParam);
	CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,0);
	return(0);
}
static int _us_DoAlignFrameTop(WPARAM wParam,LPARAM lParam)
{
	if (_fCluiFramesModuleNotStarted) return -1;

	return CLUIFrames_SetFrameAlign(wParam,alTop);
}
static int _us_DoAlignFrameBottom(WPARAM wParam,LPARAM lParam)
{
	if (_fCluiFramesModuleNotStarted) return -1;

	return CLUIFrames_SetFrameAlign(wParam,alBottom);
}
static int _us_DoAlignFrameClient(WPARAM wParam,LPARAM lParam)
{
	if (_fCluiFramesModuleNotStarted) return -1;

	return CLUIFrames_SetFrameAlign(wParam,alClient);
}


//wparam=frameid
static int _us_DoLockFrame(WPARAM wParam,LPARAM lParam)
{
	int pos;

	if (_fCluiFramesModuleNotStarted) return -1;

	if (wParam == 0) {
		pos =  lParam;
	} else {
    	pos=id2pos(wParam);
	}
	if(pos>=0&&(int)pos<g_nFramesCount)	{
		g_pfwFrames[pos].Locked=!g_pfwFrames[pos].Locked;
		CLUIFramesStoreFrameSettings(pos);
	}

	return 0;
}

//wparam=frameid
static int _us_DoSetFrameBorder(WPARAM wParam,LPARAM lParam)
{
	RECT rc;
	int FrameId,oldflags;
	HWND hw;
	boolean flt;

	if (_fCluiFramesModuleNotStarted) return -1;

	if (wParam == 0) {
		FrameId =  lParam;
	} else {
    	FrameId=id2pos(wParam);
	}
	if (FrameId==-1){return(-1);};
	flt=
		oldflags=CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS,MAKEWPARAM(FO_FLAGS,wParam),0);
	if (oldflags&F_NOBORDER)
	{
		oldflags&=(~F_NOBORDER);
	}
	else
	{
		oldflags|=F_NOBORDER;
	};
	hw = g_pfwFrames[FrameId].hWnd;
	GetWindowRect(hw,&rc);


	CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_FLAGS,wParam),oldflags);
	{
		SetWindowPos(hw,0,0,0,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE|SWP_DRAWFRAME);
	};
	return(0);
};
//wparam=frameid
static int _us_DoCollapseFrame(WPARAM wParam,LPARAM lParam)
{
	int FrameId;

	if (_fCluiFramesModuleNotStarted) return -1;

	if (wParam == 0) {
		FrameId =  lParam;
	} else {
    	FrameId=id2pos(wParam);
	}
	if(FrameId>=0&&FrameId<g_nFramesCount)
	{
		int oldHeight;

		// do not collapse/uncollapse client/locked/invisible frames
		if(g_pfwFrames[FrameId].align==alClient&&!(g_pfwFrames[FrameId].Locked||(!g_pfwFrames[FrameId].visible)||g_pfwFrames[FrameId].floating))
		{
			RECT rc;
			if(CallService(MS_CLIST_DOCKINGISDOCKED,0,0)) {return 0;};
			if (!g_CluiData.fDocked && g_CluiData.fAutoSize) {return 0;};
			GetWindowRect(pcli->hwndContactList,&rc);

			if(g_pfwFrames[FrameId].collapsed==TRUE)	{
				rc.bottom-=rc.top;
				rc.bottom-=g_pfwFrames[FrameId].height;
				g_pfwFrames[FrameId].HeightWhenCollapsed=g_pfwFrames[FrameId].height;
				g_pfwFrames[FrameId].collapsed=FALSE;
			}
			else
			{
				rc.bottom-=rc.top;
				rc.bottom+=g_pfwFrames[FrameId].HeightWhenCollapsed;
				g_pfwFrames[FrameId].collapsed=TRUE;
			}

			SetWindowPos(pcli->hwndContactList,NULL,0,0,rc.right-rc.left,rc.bottom,SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE);

			CLUIFramesStoreAllFrames();


			return 0;

		}
		if(g_pfwFrames[FrameId].Locked||(!g_pfwFrames[FrameId].visible)) return 0;

		oldHeight=g_pfwFrames[FrameId].height;

		// if collapsed, uncollapse
		if(g_pfwFrames[FrameId].collapsed==TRUE)	{
			g_pfwFrames[FrameId].HeightWhenCollapsed=g_pfwFrames[FrameId].height;
			g_pfwFrames[FrameId].height=UNCOLLAPSED_FRAME_SIZE;
			g_pfwFrames[FrameId].collapsed=FALSE;
		}
		// if uncollapsed, collapse
		else {
			g_pfwFrames[FrameId].height=g_pfwFrames[FrameId].HeightWhenCollapsed;
			g_pfwFrames[FrameId].collapsed=TRUE;
		}

		if (!g_pfwFrames[FrameId].floating)
		{

			if (!CLUIFramesFitInSize()) {
				//cant collapse,we can resize only for height<alclient frame height
				int alfrm=CLUIFramesGetalClientFrame();

				if(alfrm!=-1) {
					g_pfwFrames[FrameId].collapsed=FALSE;
					if(g_pfwFrames[alfrm].height>2*UNCOLLAPSED_FRAME_SIZE) {
						oldHeight=g_pfwFrames[alfrm].height-UNCOLLAPSED_FRAME_SIZE;
						g_pfwFrames[FrameId].collapsed=TRUE;
					}
				}else
				{
					int i,sumheight=0;
					for(i=0;i<g_nFramesCount;i++) {
						if ((g_pfwFrames[i].align!=alClient)&&(!g_pfwFrames[i].floating)&&(g_pfwFrames[i].visible)&&(!g_pfwFrames[i].needhide)) {
							sumheight+=(g_pfwFrames[i].height)+(g_nTitleBarHeight*btoint(g_pfwFrames[i].TitleBar.ShowTitleBar))+2;
							return FALSE;
						}
						if(sumheight>_nContactListHeight-0-2)
						{
							g_pfwFrames[FrameId].height=(_nContactListHeight-0-2)-sumheight;
						}

					}
				}

				g_pfwFrames[FrameId].height=oldHeight;

				if(g_pfwFrames[FrameId].collapsed==FALSE) {

					if (!g_pfwFrames[FrameId].floating)
					{
					}
					else
					{
						//SetWindowPos(Frames[FrameId].hWnd,HWND_TOP,0,0,Frames[FrameId].wndSize.right-Frames[FrameId].wndSize.left,Frames[FrameId].height,SWP_SHOWWINDOW|SWP_NOMOVE);
						SetWindowPos(g_pfwFrames[FrameId].ContainerWnd,HWND_TOP,0,0,g_pfwFrames[FrameId].wndSize.right-g_pfwFrames[FrameId].wndSize.left+6,g_pfwFrames[FrameId].height+DEFAULT_TITLEBAR_HEIGHT+4,SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOMOVE);
					};


					return -1;};//redraw not needed
			}
		};//floating test

		//CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,0);
		if (!g_pfwFrames[FrameId].floating)
		{
			CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,0);
		}
		else
		{
			//SetWindowPos(Frames[FrameId].hWnd,HWND_TOP,0,0,Frames[FrameId].wndSize.right-Frames[FrameId].wndSize.left,Frames[FrameId].height,SWP_SHOWWINDOW|SWP_NOMOVE);
			RECT contwnd;
			GetWindowRect(g_pfwFrames[FrameId].ContainerWnd,&contwnd);
			contwnd.top=contwnd.bottom-contwnd.top;//height
			contwnd.left=contwnd.right-contwnd.left;//width

			contwnd.top-=(oldHeight-g_pfwFrames[FrameId].height);//newheight
			SetWindowPos(g_pfwFrames[FrameId].ContainerWnd,HWND_TOP,0,0,contwnd.left,contwnd.top,SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOMOVE);
		};
		CLUIFramesStoreAllFrames();
		return(0);
	}
	else
		return -1;
}

static int CLUIFramesLoadMainMenu()
{
	if (_fCluiFramesModuleNotStarted)
		return -1;

	if(_hmiRoot!=(HGENMENU)-1) {
		CallService(MS_CLIST_REMOVEMAINMENUITEM,(WPARAM)_hmiRoot,0);
		_hmiRoot=(HGENMENU)-1;
	}

	CLISTMENUITEM mi = { 0 };
	mi.cbSize=sizeof(mi);
	// create root menu
	mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTHANDLE;
	mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_MIRANDA);
	mi.position = 3000090000;
	mi.pszName = LPGEN("Frames");
	_hmiRoot = Menu_AddMainMenuItem(&mi);
	DestroyIcon_protect(mi.hIcon);
	// create frames menu
	int separator=3000200000;
	for (int i=0; i < g_nFramesCount; i++) {
		mi.hIcon = g_pfwFrames[i].TitleBar.hicon;
		mi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR;
		mi.position = separator;
		mi.hParentMenu = _hmiRoot;
		mi.ptszName = g_pfwFrames[i].TitleBar.tbname ? g_pfwFrames[i].TitleBar.tbname : g_pfwFrames[i].Name;
		mi.pszService = 0;
		g_pfwFrames[i].MenuHandles.MainMenuItem = Menu_AddMainMenuItem(&mi);
		CLUIFramesCreateMenuForFrame(g_pfwFrames[i].id,(int)g_pfwFrames[i].MenuHandles.MainMenuItem,separator,Menu_AddMainMenuItem);
		CLUIFramesModifyMainMenuItems(g_pfwFrames[i].id,0);
		CallService(MS_CLIST_FRAMEMENUNOTIFY,(WPARAM)g_pfwFrames[i].id,(LPARAM)g_pfwFrames[i].MenuHandles.MainMenuItem);
		separator++;
	}

	separator+=100000;

	// create "show all frames" menu
	mi.hIcon = NULL;
	mi.flags = CMIF_ROOTHANDLE;
	mi.position = separator++;
	mi.hParentMenu = _hmiRoot;
	mi.pszName = LPGEN("Show All Frames");
	mi.pszService = MS_CLIST_FRAMES_SHOWALLFRAMES;
	Menu_AddMainMenuItem(&mi);

	// create "show all titlebars" menu
	mi.position = separator++;
	mi.pszName = LPGEN("Show All Titlebars");
	mi.pszService = MS_CLIST_FRAMES_SHOWALLFRAMESTB;
	Menu_AddMainMenuItem(&mi);

	// create "hide all titlebars" menu
	mi.position = separator++;
	mi.pszName = LPGEN("Hide All Titlebars");
	mi.pszService = MS_CLIST_FRAMES_HIDEALLFRAMESTB;
	Menu_AddMainMenuItem(&mi);
	return 0;
}

static HFONT CLUILoadTitleBarFont()
{
	char facename[]="MS Shell Dlg";
	HFONT hfont;
	LOGFONTA logfont;
	memset(&logfont,0,sizeof(logfont));
	memmove(logfont.lfFaceName,facename,sizeof(facename));
	logfont.lfWeight=FW_NORMAL;
	logfont.lfHeight=-10;
	logfont.lfCharSet=DEFAULT_CHARSET;
	hfont=CreateFontIndirectA(&logfont);
	return hfont;
}


//wparam=(CLISTFrame*)clfrm
static int _us_DoAddFrame(WPARAM wParam,LPARAM lParam)
{
	int style,retval;
	//char * CustomName=NULL;
	CLISTFrame *clfrm=(CLISTFrame *)wParam;

	if(pcli->hwndContactList==0) return -1;
	if (_fCluiFramesModuleNotStarted) return -1;
	if(clfrm->cbSize!=sizeof(CLISTFrame)) return -1;
	if (!(_hTitleBarFont)) _hTitleBarFont = CLUILoadTitleBarFont();

	g_pfwFrames=(FRAMEWND*)realloc(g_pfwFrames,sizeof(FRAMEWND)*(g_nFramesCount+1));

	memset(&g_pfwFrames[g_nFramesCount],0,sizeof(FRAMEWND));
	/*   //removed buggy code
	if (clfrm->name && 0 )
	{
		CustomName=ModernDBGetStringA(NULL,"CUSTOM_CLUI_FRAMES",AS(buff,"CustomName_",clfrm->name));
		Frames[nFramescount].TitleBar.BackColour=(COLORREF)DBGetContactSettingDword(NULL,"CUSTOM_CLUI_FRAMES",AS(buff,"CustomBackColor_",clfrm->name),GetSysColor(COLOR_3DFACE));
		Frames[nFramescount].TitleBar.TextColour=(COLORREF)DBGetContactSettingDword(NULL,"CUSTOM_CLUI_FRAMES",AS(buff,"CustomTextColor_",clfrm->name),GetSysColor(COLOR_WINDOWTEXT));
		if (CustomName)
		{
			if (clfrm->name) mir_free_and_nill(clfrm->name);
			clfrm->name=mir_strdup(CustomName);
			mir_free_and_nill(CustomName);
		}
	}
	*/
	g_pfwFrames[g_nFramesCount].id=_iNextFrameId++;
	g_pfwFrames[g_nFramesCount].align=clfrm->align;
	g_pfwFrames[g_nFramesCount].hWnd=clfrm->hWnd;
	g_pfwFrames[g_nFramesCount].height=clfrm->height;
	g_pfwFrames[g_nFramesCount].TitleBar.hicon=clfrm->hIcon;
	//Frames[nFramescount].TitleBar.BackColour;
	g_pfwFrames[g_nFramesCount].floating=FALSE;
	if (clfrm->Flags&F_NO_SUBCONTAINER || !g_CluiData.fLayered)
		g_pfwFrames[g_nFramesCount].OwnerWindow=(HWND)-2;
	else g_pfwFrames[g_nFramesCount].OwnerWindow=0;

	//override tbbtip
	//clfrm->Flags|=F_SHOWTBTIP;
	//
	if (db_get_b(0,CLUIFrameModule,"RemoveAllBorders",0)==1)
	{
		clfrm->Flags|=F_NOBORDER;
	};
	g_pfwFrames[g_nFramesCount].dwFlags=clfrm->Flags;

    if (clfrm->name==NULL||((clfrm->Flags&F_UNICODE) ? lstrlenW(clfrm->wname) : lstrlenA(clfrm->name))==0) {
        g_pfwFrames[g_nFramesCount].Name=(LPTSTR)mir_alloc(255 * sizeof(TCHAR));
        GetClassName(g_pfwFrames[g_nFramesCount].hWnd,g_pfwFrames[g_nFramesCount].Name,255);
    }
    else
	{
        g_pfwFrames[g_nFramesCount].Name=(clfrm->Flags&F_UNICODE) ? mir_u2t(clfrm->wname) : mir_a2t(clfrm->name);
	}
	g_pfwFrames[g_nFramesCount].szName=mir_t2a(g_pfwFrames[g_nFramesCount].Name);
    if (IsBadCodePtr((FARPROC)clfrm->TBname) || clfrm->TBname==NULL
        || ((clfrm->Flags&F_UNICODE) ? lstrlenW(clfrm->TBwname) : lstrlenA(clfrm->TBname)) == 0)
        g_pfwFrames[g_nFramesCount].TitleBar.tbname=mir_tstrdup(g_pfwFrames[g_nFramesCount].Name);
    else
        g_pfwFrames[g_nFramesCount].TitleBar.tbname=(clfrm->Flags&F_UNICODE) ? mir_u2t(clfrm->TBwname) : mir_a2t(clfrm->TBname);
	g_pfwFrames[g_nFramesCount].TitleBar.sztbname=mir_t2a(g_pfwFrames[g_nFramesCount].TitleBar.tbname);
	g_pfwFrames[g_nFramesCount].needhide=FALSE;
	g_pfwFrames[g_nFramesCount].TitleBar.ShowTitleBar=(clfrm->Flags&F_SHOWTB?TRUE:FALSE);
	g_pfwFrames[g_nFramesCount].TitleBar.ShowTitleBarTip=(clfrm->Flags&F_SHOWTBTIP?TRUE:FALSE);

	g_pfwFrames[g_nFramesCount].collapsed = (clfrm->Flags&F_UNCOLLAPSED)?FALSE:TRUE;


	g_pfwFrames[g_nFramesCount].Locked = clfrm->Flags&F_LOCKED?TRUE:FALSE;
	g_pfwFrames[g_nFramesCount].visible = clfrm->Flags&F_VISIBLE?TRUE:FALSE;

	g_pfwFrames[g_nFramesCount].UseBorder=((clfrm->Flags&F_NOBORDER)||g_CluiData.fLayered)?FALSE:TRUE;

	//Frames[nFramescount].OwnerWindow=0;



	g_pfwFrames[g_nFramesCount].TitleBar.hwnd
		=CreateWindow(CLUIFrameTitleBarClassName,g_pfwFrames[g_nFramesCount].Name,
		(db_get_b(0,CLUIFrameModule,"RemoveAllTitleBarBorders",1)?0:WS_BORDER)

		|WS_CHILD|WS_CLIPCHILDREN|
		(g_pfwFrames[g_nFramesCount].TitleBar.ShowTitleBar?WS_VISIBLE:0)|
		WS_CLIPCHILDREN,
		0,0,0,0,pcli->hwndContactList,NULL,g_hInst,NULL);
	SetWindowLongPtr(g_pfwFrames[g_nFramesCount].TitleBar.hwnd,GWLP_USERDATA,g_pfwFrames[g_nFramesCount].id);


	g_pfwFrames[g_nFramesCount].TitleBar.hwndTip
		=CreateWindowExA(0, TOOLTIPS_CLASSA, NULL,
		WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
		CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT,
		pcli->hwndContactList, NULL, g_hInst,
		NULL);

	SetWindowPos(g_pfwFrames[g_nFramesCount].TitleBar.hwndTip, HWND_TOPMOST,0, 0, 0, 0,
		SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
	{
		TOOLINFOA ti;
		int res;

		ZeroMemory(&ti,sizeof(ti));
		ti.cbSize=sizeof(ti);
		ti.lpszText="";
		ti.hinst=g_hInst;
		ti.uFlags=TTF_IDISHWND|TTF_SUBCLASS ;
		ti.uId=(UINT_PTR)g_pfwFrames[g_nFramesCount].TitleBar.hwnd;
		res=SendMessageA(g_pfwFrames[g_nFramesCount].TitleBar.hwndTip,TTM_ADDTOOL,(WPARAM)0,(LPARAM)&ti);
	}

	SendMessageA(g_pfwFrames[g_nFramesCount].TitleBar.hwndTip,TTM_ACTIVATE,(WPARAM)g_pfwFrames[g_nFramesCount].TitleBar.ShowTitleBarTip,0);

	g_pfwFrames[g_nFramesCount].oldstyles=GetWindowLongPtr(g_pfwFrames[g_nFramesCount].hWnd,GWL_STYLE);
	g_pfwFrames[g_nFramesCount].TitleBar.oldstyles=GetWindowLongPtr(g_pfwFrames[g_nFramesCount].TitleBar.hwnd,GWL_STYLE);
	//Frames[nFramescount].FloatingPos.x=

	retval=g_pfwFrames[g_nFramesCount].id;
	g_pfwFrames[g_nFramesCount].order=g_nFramesCount+1;
	g_nFramesCount++;


	CLUIFramesLoadFrameSettings(id2pos(retval));
	if (g_pfwFrames[g_nFramesCount-1].collapsed==FALSE)
	{
		g_pfwFrames[g_nFramesCount-1].height=0;
	}

	// create frame


	//    else Frames[nFramescount-1].height=Frames[nFramescount-1].HeightWhenCollapsed;

	style=GetWindowLongPtr(g_pfwFrames[g_nFramesCount-1].hWnd,GWL_STYLE);
	style&=(~WS_BORDER);
	style|=(((g_pfwFrames[g_nFramesCount-1].UseBorder)&&!g_CluiData.fLayered)?WS_BORDER:0);
	SetWindowLongPtr(g_pfwFrames[g_nFramesCount-1].hWnd,GWL_STYLE,style);
	SetWindowLongPtr(g_pfwFrames[g_nFramesCount-1].TitleBar.hwnd,GWL_STYLE,style& ~(WS_VSCROLL | WS_HSCROLL));
	SetWindowLongPtr(g_pfwFrames[g_nFramesCount-1].TitleBar.hwnd,GWL_STYLE,GetWindowLongPtr(g_pfwFrames[g_nFramesCount-1].TitleBar.hwnd,GWL_STYLE)&~(WS_VSCROLL|WS_HSCROLL));

	if (g_pfwFrames[g_nFramesCount-1].order==0){g_pfwFrames[g_nFramesCount-1].order=g_nFramesCount;};


	//need to enlarge parent
	{
		RECT mainRect;
		int mainHeight, minHeight;
		GetWindowRect(pcli->hwndContactList,&mainRect);
		mainHeight=mainRect.bottom-mainRect.top;
		minHeight=CLUIFrames_GetTotalHeight();
		if (mainHeight<minHeight)
		{
			BOOL Upward=FALSE;
			Upward=!g_CluiData.fDocked&&g_CluiData.fAutoSize&&db_get_b(NULL,"CLUI","AutoSizeUpward",SETTING_AUTOSIZEUPWARD_DEFAULT);

			if (Upward)
				mainRect.top=mainRect.bottom-minHeight;
			else
				mainRect.bottom=mainRect.top+minHeight;
			SetWindowPos(pcli->hwndContactList,NULL,mainRect.left,mainRect.top,mainRect.right-mainRect.left, mainRect.bottom-mainRect.top, SWP_NOZORDER|SWP_NOREDRAW|SWP_NOACTIVATE|SWP_NOSENDCHANGING);
		}
		GetWindowRect(pcli->hwndContactList,&mainRect);
		mainHeight=mainRect.bottom-mainRect.top;
		//if (mainHeight<minHeight)
		//	  DebugBreak();
	}
	_nClientFrameId = eUnknownId;//recalc it
	CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,0);

	if (g_pfwFrames[g_nFramesCount-1].floating)
	{

		g_pfwFrames[g_nFramesCount-1].floating=FALSE;
		//SetWindowPos(Frames[nFramescount-1].hw
		CLUIFrames_SetFrameFloat(retval,1);//lparam=1 use stored width and height
	}
	else
		CLUIFrames_SetFrameFloat(retval,2);

	/** Remove	*/
	//_ExtFramesSrv_AddFrame( wParam,  lParam);

	return retval;
}

static int _us_DoRemoveFrame(WPARAM wParam,LPARAM lParam)
{
	int pos;
	if (_fCluiFramesModuleNotStarted) return -1;

	pos=id2pos(wParam);

	if (pos<0||pos>g_nFramesCount){return(-1);};

	if (g_pfwFrames[pos].Name!=NULL) mir_free_and_nill(g_pfwFrames[pos].Name);
	if (g_pfwFrames[pos].szName!=NULL) mir_free_and_nill(g_pfwFrames[pos].szName);
	if (g_pfwFrames[pos].TitleBar.tbname!=NULL) mir_free_and_nill(g_pfwFrames[pos].TitleBar.tbname);
	if (g_pfwFrames[pos].TitleBar.sztbname!=NULL) mir_free_and_nill(g_pfwFrames[pos].TitleBar.sztbname);
	if (g_pfwFrames[pos].TitleBar.tooltip!=NULL) mir_free_and_nill(g_pfwFrames[pos].TitleBar.tooltip);
	if (g_pfwFrames[pos].TitleBar.sztooltip!=NULL) mir_free_and_nill(g_pfwFrames[pos].TitleBar.sztooltip);
	DestroyWindow(g_pfwFrames[pos].hWnd);
	g_pfwFrames[pos].hWnd=(HWND)-1;
	DestroyWindow(g_pfwFrames[pos].TitleBar.hwnd);
	if(g_pfwFrames[pos].TitleBar.hwndTip)
		DestroyWindow(g_pfwFrames[pos].TitleBar.hwndTip);
	g_pfwFrames[pos].TitleBar.hwnd=(HWND)-1;
	if(g_pfwFrames[pos].ContainerWnd && g_pfwFrames[pos].ContainerWnd!=(HWND)-1) DestroyWindow(g_pfwFrames[pos].ContainerWnd);
	g_pfwFrames[pos].ContainerWnd=(HWND)-1;
	if (g_pfwFrames[pos].TitleBar.hmenu) DestroyMenu(g_pfwFrames[pos].TitleBar.hmenu);
	g_pfwFrames[pos].PaintCallbackProc = NULL;
    if (g_pfwFrames[pos].UpdateRgn) DeleteObject(g_pfwFrames[pos].UpdateRgn);

	if (g_pfwFrames[pos].OwnerWindow!=(HWND)-1
		&& g_pfwFrames[pos].OwnerWindow!=(HWND)-2
		&& g_pfwFrames[pos].OwnerWindow!=(HWND)0)
		DestroyWindow(g_pfwFrames[pos].OwnerWindow);

	g_pfwFrames[pos].OwnerWindow=NULL;
	RemoveItemFromList(pos,&g_pfwFrames,&g_nFramesCount);

	CLUI__cliInvalidateRect(pcli->hwndContactList,NULL,TRUE);
	CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,0);
	CLUI__cliInvalidateRect(pcli->hwndContactList,NULL,TRUE);

	return(0);
};


static int CLUIFramesForceUpdateTB(const FRAMEWND *Frame)
{
	if (Frame->TitleBar.hwnd!=0) RedrawWindow(Frame->TitleBar.hwnd,NULL,NULL,RDW_ALLCHILDREN|RDW_UPDATENOW|RDW_ERASE|RDW_INVALIDATE|RDW_FRAME);
	//UpdateWindow(Frame->TitleBar.hwnd);
	return 0;
}

static int CLUIFramesForceUpdateFrame(const FRAMEWND *Frame)
{
	if (Frame->hWnd!=0)
	{
		RedrawWindow(Frame->hWnd,NULL,NULL,RDW_UPDATENOW|RDW_FRAME|RDW_ERASE|RDW_INVALIDATE);
		UpdateWindow(Frame->hWnd);
	};
	if(Frame->floating)
	{
		if (Frame->ContainerWnd!=0)  RedrawWindow(Frame->ContainerWnd,NULL,NULL,RDW_UPDATENOW|RDW_ALLCHILDREN|RDW_ERASE|RDW_INVALIDATE|RDW_FRAME);
		//UpdateWindow(Frame->ContainerWnd);
	};
	return 0;
}

static int CLUIFrameMoveResize(const FRAMEWND *Frame)
{
	// we need to show or hide the frame?
	if(Frame->visible&&(!Frame->needhide)) {
		if (Frame->OwnerWindow!=(HWND)-2 &&Frame->OwnerWindow)
		{
			//          CLUI_ShowWindowMod(Frame->OwnerWindow,SW_SHOW);
		}
		CLUI_ShowWindowMod(Frame->hWnd,SW_SHOW/*NOACTIVATE*/);
		CLUI_ShowWindowMod(Frame->TitleBar.hwnd,Frame->TitleBar.ShowTitleBar==TRUE?SW_SHOW/*NOACTIVATE*/:SW_HIDE);
	}
	else {
		if (Frame->OwnerWindow && Frame->OwnerWindow!=(HWND)(-1)&& Frame->OwnerWindow!=(HWND)(-2))
		{
			CLUI_ShowWindowMod(Frame->OwnerWindow,SW_HIDE);
		}
		CLUI_ShowWindowMod(Frame->hWnd,SW_HIDE);
		CLUI_ShowWindowMod(Frame->TitleBar.hwnd,SW_HIDE);
		return(0);
	}

	if (Frame->OwnerWindow&&Frame->OwnerWindow!=(HWND)-2 )
	{
		RECT pr;
		POINT Off={0};

		ClientToScreen(pcli->hwndContactList,&Off);
		GetWindowRect(pcli->hwndContactList,&pr);

		if ( Frame->visible && (!Frame->collapsed || Frame->wndSize.bottom-Frame->wndSize.top == 0))
		{
			ShowWindowAsync( Frame->OwnerWindow, SW_HIDE );
			ShowWindowAsync( Frame->hWnd, SW_HIDE );
		}

		{
			SetWindowPos(Frame->OwnerWindow,NULL,Frame->wndSize.left+Off.x,Frame->wndSize.top+Off.y,
				Frame->wndSize.right-Frame->wndSize.left,
				Frame->wndSize.bottom-Frame->wndSize.top,SWP_NOZORDER|SWP_NOACTIVATE );   //--=-=

			SetWindowPos(Frame->hWnd,NULL,0,0,
				Frame->wndSize.right-Frame->wndSize.left,
				Frame->wndSize.bottom-Frame->wndSize.top,SWP_NOZORDER|SWP_NOACTIVATE);
		}
		// set titlebar position
		if(Frame->TitleBar.ShowTitleBar) {
			SetWindowPos(Frame->TitleBar.hwnd,NULL,Frame->wndSize.left,Frame->wndSize.top-g_nTitleBarHeight-g_CluiData.nGapBetweenTitlebar,
				Frame->wndSize.right-Frame->wndSize.left,
				g_nTitleBarHeight,SWP_NOZORDER|SWP_NOACTIVATE	);
		}
		if ( Frame->visible && IsWindowVisible( pcli->hwndContactList ) && Frame->collapsed && Frame->wndSize.bottom-Frame->wndSize.top != 0 )
		{
			ShowWindow( Frame->OwnerWindow, SW_SHOW );
			ShowWindow( Frame->hWnd, SW_SHOW );
		}

	}
	else
	{
		// set frame position
		SetWindowPos(Frame->hWnd,NULL,Frame->wndSize.left,Frame->wndSize.top,
			Frame->wndSize.right-Frame->wndSize.left,
			Frame->wndSize.bottom-Frame->wndSize.top,SWP_NOZORDER|SWP_NOACTIVATE);
		// set titlebar position
		if(Frame->TitleBar.ShowTitleBar) {
			SetWindowPos(Frame->TitleBar.hwnd,NULL,Frame->wndSize.left,Frame->wndSize.top-g_nTitleBarHeight-g_CluiData.nGapBetweenTitlebar,
				Frame->wndSize.right-Frame->wndSize.left,
				g_nTitleBarHeight,SWP_NOZORDER|SWP_NOACTIVATE);

		}
	}
	//	Sleep(0);
	return 0;
}

static BOOL CLUIFramesFitInSize(void)
{
	int i;
	int sumheight=0;
	int tbh=0; // title bar height
	int clientfrm;
	clientfrm=CLUIFramesGetalClientFrame();
	if(clientfrm!=-1)
		tbh=g_nTitleBarHeight*btoint(g_pfwFrames[clientfrm].TitleBar.ShowTitleBar);

	for(i=0;i<g_nFramesCount;i++) {
		if ((g_pfwFrames[i].align!=alClient)&&(!g_pfwFrames[i].floating)&&(g_pfwFrames[i].visible)&&(!g_pfwFrames[i].needhide)) {
			sumheight+=(g_pfwFrames[i].height)+(g_nTitleBarHeight*btoint(g_pfwFrames[i].TitleBar.ShowTitleBar))+2/*+btoint(Frames[i].UseBorder)*2*/;
			if(sumheight>_nContactListHeight-tbh-2)
			{
				if (!g_CluiData.fDocked && g_CluiData.fAutoSize)
				{
					return TRUE; //Can be required to enlarge
				}
				return FALSE;
			}
		}
	}
	return TRUE;
}
int CLUIFrames_GetTotalHeight()
{
	int i;
	int sumheight=0;
	RECT border;
	if(pcli->hwndContactList==NULL) return 0;

	for(i=0;i<g_nFramesCount;i++)
	{
		if ((g_pfwFrames[i].visible)&&(!g_pfwFrames[i].needhide)&&(!g_pfwFrames[i].floating)&&(pcli->hwndContactTree)&& (g_pfwFrames[i].hWnd!=pcli->hwndContactTree))
			sumheight+=(g_pfwFrames[i].height)+(g_nTitleBarHeight*btoint(g_pfwFrames[i].TitleBar.ShowTitleBar));
	};

	GetBorderSize(pcli->hwndContactList,&border);

	//GetWindowRect(pcli->hwndContactList,&winrect);
	//GetClientRect(pcli->hwndContactList,&clirect);
	//	clirect.bottom-=clirect.top;
	//	clirect.bottom+=border.top+border.bottom;
	//allbord=(winrect.bottom-winrect.top)-(clirect.bottom-clirect.top);

	//TODO minsize
	sumheight+=g_CluiData.TopClientMargin;
	sumheight+=g_CluiData.BottomClientMargin;
	return  max(db_get_w(NULL,"CLUI","MinHeight",SETTING_MINHEIGTH_DEFAULT),
		(sumheight+border.top+border.bottom));
}

int CLUIFramesGetMinHeight()
{
	int i,tbh,clientfrm,sumheight=0;
	RECT border;
	int allbord=0;
	if(pcli->hwndContactList==NULL) return 0;


	// search for alClient frame and get the titlebar's height
	tbh=0;
	clientfrm=CLUIFramesGetalClientFrame();
	if(clientfrm!=-1)
		tbh=g_nTitleBarHeight*btoint(g_pfwFrames[clientfrm].TitleBar.ShowTitleBar);

	for(i=0;i<g_nFramesCount;i++)
	{
		if ((g_pfwFrames[i].align!=alClient)&&(g_pfwFrames[i].visible)&&(!g_pfwFrames[i].needhide)&&(!g_pfwFrames[i].floating))
		{
			RECT wsize;

			GetWindowRect(g_pfwFrames[i].hWnd,&wsize);
			sumheight+=(wsize.bottom-wsize.top)+(g_nTitleBarHeight*btoint(g_pfwFrames[i].TitleBar.ShowTitleBar));
		}
	};

	GetBorderSize(pcli->hwndContactList,&border);

	//GetWindowRect(pcli->hwndContactList,&winrect);
	//GetClientRect(pcli->hwndContactList,&clirect);
	//	clirect.bottom-=clirect.top;
	//	clirect.bottom+=border.top+border.bottom;
	//allbord=(winrect.bottom-winrect.top)-(clirect.bottom-clirect.top);

	//TODO minsize
	sumheight+=g_CluiData.TopClientMargin;
	sumheight+=g_CluiData.BottomClientMargin;
	return  max(db_get_w(NULL,"CLUI","MinHeight",SETTING_MINHEIGTH_DEFAULT),
		(sumheight+border.top+border.bottom+allbord+tbh)       );
}




static int CLUIFramesResizeFrames(const RECT newsize)
{
	int sumheight=9999999,newheight;
	int prevframe,prevframebottomline;
	int tbh,curfrmtbh;
	int drawitems;
	int clientfrm;
	int i,j;
	int sepw=GapBetweenFrames;
	int topBorder=newsize.top;
	int minHeight=CLUIFrames_GetTotalHeight();
	SortData *sdarray;


	g_CluiData.nGapBetweenTitlebar=(int)db_get_dw(NULL,"CLUIFrames","GapBetweenTitleBar",SETTING_GAPTITLEBAR_DEFAULT);
	GapBetweenFrames=db_get_dw(NULL,"CLUIFrames","GapBetweenFrames",SETTING_GAPFRAMES_DEFAULT);
	sepw=GapBetweenFrames;

	if(g_nFramesCount<1) return 0;
	newheight=newsize.bottom-newsize.top;

	// search for alClient frame and get the titlebar's height
	tbh=0;
	clientfrm=CLUIFramesGetalClientFrame();
	if(clientfrm!=-1)
		tbh=(g_nTitleBarHeight+g_CluiData.nGapBetweenTitlebar)*btoint(g_pfwFrames[clientfrm].TitleBar.ShowTitleBar);

	for(i=0;i<g_nFramesCount;i++)
	{
		if (!g_pfwFrames[i].floating)
		{
			g_pfwFrames[i].needhide=FALSE;
			g_pfwFrames[i].wndSize.left=newsize.left;
			g_pfwFrames[i].wndSize.right=newsize.right;

		};
	};
	{
		//sorting stuff
		sdarray=(SortData*)malloc(sizeof(SortData)*g_nFramesCount);
		if (sdarray==NULL){return(-1);};
		for(i=0;i<g_nFramesCount;i++)
		{sdarray[i].order=g_pfwFrames[i].order;
		sdarray[i].realpos=i;
		};
		qsort(sdarray,g_nFramesCount,sizeof(SortData),sortfunc);

	}

	drawitems=g_nFramesCount;

	while(sumheight>(newheight-tbh)&&drawitems>0) {
		sumheight=0;
		drawitems=0;
		for(i=0;i<g_nFramesCount;i++) {
			if (((g_pfwFrames[i].align!=alClient))&&(!g_pfwFrames[i].floating)&&(g_pfwFrames[i].visible)&&(!g_pfwFrames[i].needhide)) {
				drawitems++;
				curfrmtbh=(g_nTitleBarHeight+g_CluiData.nGapBetweenTitlebar)*btoint(g_pfwFrames[i].TitleBar.ShowTitleBar);
				sumheight+=(g_pfwFrames[i].height)+curfrmtbh+(i > 0 ? sepw : 0)+( (g_pfwFrames[i].UseBorder &&!g_CluiData.fLayered)?2:0);
				if(sumheight>newheight-tbh) {
					sumheight-=(g_pfwFrames[i].height)+curfrmtbh + (i > 0 ? sepw : 0);
					g_pfwFrames[i].needhide=!g_CluiData.fDocked && g_CluiData.fAutoSize?FALSE:TRUE;
					drawitems--;
					break;
				}
			}
		}
	}

	prevframe=-1;
	prevframebottomline=topBorder;
	for(j=0;j<g_nFramesCount;j++) {
		//move all alTop frames
		i=sdarray[j].realpos;
		if ((!g_pfwFrames[i].needhide)&&(!g_pfwFrames[i].floating)&&(g_pfwFrames[i].visible)&&(g_pfwFrames[i].align==alTop)) {
			curfrmtbh=(g_nTitleBarHeight+g_CluiData.nGapBetweenTitlebar)*btoint(g_pfwFrames[i].TitleBar.ShowTitleBar);
			g_pfwFrames[i].wndSize.top=prevframebottomline+(i > 0 ? sepw : 0)+(curfrmtbh);
			g_pfwFrames[i].wndSize.bottom=g_pfwFrames[i].height+g_pfwFrames[i].wndSize.top+((g_pfwFrames[i].UseBorder &&!g_CluiData.fLayered)?2:0);
			g_pfwFrames[i].prevvisframe=prevframe;
			prevframe=i;
			prevframebottomline=g_pfwFrames[i].wndSize.bottom;
			if(prevframebottomline>newheight){
				//prevframebottomline-=Frames[i].height+(curfrmtbh+1);
				//Frames[i].needhide=TRUE;
			}
		}
	}

	if(sumheight<newheight) {
		for(j=0;j<g_nFramesCount;j++) {
			//move alClient frame
			i=sdarray[j].realpos;
			if ((!g_pfwFrames[i].needhide)&&(!g_pfwFrames[i].floating)&&(g_pfwFrames[i].visible)&&(g_pfwFrames[i].align==alClient)) {
				int oldh;
				g_pfwFrames[i].wndSize.top=prevframebottomline+(j > 0 ? sepw : 0)+(tbh);
				g_pfwFrames[i].wndSize.bottom=g_pfwFrames[i].wndSize.top+newheight-sumheight-tbh-(j > 0 ? sepw : 0);

				oldh=g_pfwFrames[i].height;
				g_pfwFrames[i].height=g_pfwFrames[i].wndSize.bottom-g_pfwFrames[i].wndSize.top;
				g_pfwFrames[i].prevvisframe=prevframe;
				prevframe=i;
				prevframebottomline=g_pfwFrames[i].wndSize.bottom;
				if(prevframebottomline>newheight) {
					//prevframebottomline-=Frames[i].height+(tbh+1);
					//Frames[i].needhide=TRUE;
				}
				break;
			}
		}
	}

	//newheight
	prevframebottomline=newheight+sepw+topBorder;
	//prevframe=-1;
	for(j=g_nFramesCount-1;j>=0;j--) {
		//move all alBottom frames
		i=sdarray[j].realpos;
		if ((g_pfwFrames[i].visible)&&(!g_pfwFrames[i].floating)&&(!g_pfwFrames[i].needhide)&&(g_pfwFrames[i].align==alBottom)) {
			curfrmtbh=(g_nTitleBarHeight+g_CluiData.nGapBetweenTitlebar)*btoint(g_pfwFrames[i].TitleBar.ShowTitleBar);

			g_pfwFrames[i].wndSize.bottom=prevframebottomline-(j > 0 ? sepw : 0);
			g_pfwFrames[i].wndSize.top=g_pfwFrames[i].wndSize.bottom-g_pfwFrames[i].height-((g_pfwFrames[i].UseBorder &&!g_CluiData.fLayered)?2:0);
			g_pfwFrames[i].prevvisframe=prevframe;
			prevframe=i;
			prevframebottomline=g_pfwFrames[i].wndSize.top/*-1*/-curfrmtbh;
			if(prevframebottomline>newheight) {

			}
		}
	}
	for(i=0;i<g_nFramesCount;i++)
		if(g_pfwFrames[i].TitleBar.ShowTitleBar)
			SetRect(&g_pfwFrames[i].TitleBar.wndSize,g_pfwFrames[i].wndSize.left,g_pfwFrames[i].wndSize.top-g_nTitleBarHeight-g_CluiData.nGapBetweenTitlebar,g_pfwFrames[i].wndSize.right,g_pfwFrames[i].wndSize.top-g_CluiData.nGapBetweenTitlebar);
	if (sdarray!=NULL){free(sdarray);sdarray=NULL;};



	return 0;
}

static int SizeMoveNewSizes()
{
	int i;
	for(i=0;i<g_nFramesCount;i++)
	{

		if (g_pfwFrames[i].floating){
			CLUIFrameResizeFloatingFrame(i);
		}else
		{
			CLUIFrameMoveResize(&g_pfwFrames[i]);
		};
	}
	return 0;
}


static int CLUIFramesResize(RECT newsize)
{
	CLUIFramesResizeFrames(newsize);
	SizeMoveNewSizes();
	return 0;
}
int CLUIFrames_ApplyNewSizes(int mode)
{
	int i;
	g_CluiData.mutexPreventDockMoving=0;
	for(i=0;i<g_nFramesCount;i++) {
		if ( (mode==1 && g_pfwFrames[i].OwnerWindow!=(HWND)-2 && g_pfwFrames[i].OwnerWindow) ||
			(mode==2 && g_pfwFrames[i].OwnerWindow==(HWND)-2) ||
			(mode==3))
			if (g_pfwFrames[i].floating){
				CLUIFrameResizeFloatingFrame(i);
			}else
			{
				CLUIFrameMoveResize(&g_pfwFrames[i]);
			};
	}
	if (IsWindowVisible(pcli->hwndContactList))
	{
		ske_DrawNonFramedObjects(1,0);
		CallService(MS_SKINENG_INVALIDATEFRAMEIMAGE,0,0);
	}
	g_CluiData.mutexPreventDockMoving=1;
	return 0;
}

static int _us_DoUpdateFrame(WPARAM wParam,LPARAM lParam)
{
	if (_fCluiFramesModuleNotStarted) return -1;
	if(wParam==-1) { CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0); return 0;}
	if(lParam&FU_FMPOS)	CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,1);

	int pos = id2pos( wParam );
	if ( pos < 0 || pos >= g_nFramesCount ) {  return -1; }
	if ( lParam&FU_TBREDRAW )	CLUIFramesForceUpdateTB( &g_pfwFrames[pos] );
	if ( lParam&FU_FMREDRAW )	CLUIFramesForceUpdateFrame( &g_pfwFrames[pos] );
	return 0;
}

int CLUIFrames_OnClistResize_mod(WPARAM wParam,LPARAM mode)
{
	RECT nRect;
	int tick;
	GapBetweenFrames=db_get_dw(NULL,"CLUIFrames","GapBetweenFrames",SETTING_GAPFRAMES_DEFAULT);
	g_CluiData.nGapBetweenTitlebar=db_get_dw(NULL,"CLUIFrames","GapBetweenTitleBar",SETTING_GAPTITLEBAR_DEFAULT);
	if (_fCluiFramesModuleNotStarted) return -1;

	GetClientRect(pcli->hwndContactList,&nRect);

	nRect.left+=g_CluiData.LeftClientMargin;
	nRect.right-=g_CluiData.RightClientMargin;
	nRect.top+=g_CluiData.TopClientMargin;
	nRect.bottom-=g_CluiData.BottomClientMargin;
	//	g_CluiData.mutexPreventDockMoving=0;
	tick=GetTickCount();
	CLUIFramesResize(nRect);
	if (mode==0) CLUIFrames_ApplyNewSizes(3);

	tick=GetTickCount()-tick;

	Sleep(0);

	//dont save to database too many times
	if(GetTickCount()-_dwLastStoreTick>1000){ CLUIFramesStoreAllFrames();_dwLastStoreTick=GetTickCount();};

	return 0;
}

int SizeFramesByWindowRect(RECT *r, HDWP * PosBatch, int mode)
{
	RECT nRect;
	if (_fCluiFramesModuleNotStarted) return -1;

	g_CluiData.nGapBetweenTitlebar=(int)db_get_dw(NULL,"CLUIFrames","GapBetweenTitleBar",SETTING_GAPTITLEBAR_DEFAULT);
	GapBetweenFrames=db_get_dw(NULL,"CLUIFrames","GapBetweenFrames",SETTING_GAPFRAMES_DEFAULT);
	nRect.left=0;
	nRect.top=0;
	nRect.right=r->right-r->left;
	nRect.bottom=r->bottom-r->top;
	nRect.left+=g_CluiData.LeftClientMargin;
	nRect.right-=g_CluiData.RightClientMargin;
	nRect.top+=g_CluiData.TopClientMargin;
	nRect.bottom-=g_CluiData.BottomClientMargin;
	CLUIFramesResizeFrames(nRect);
	{
		int i;
		for(i=0;i<g_nFramesCount;i++)
		{
			int dx;
			int dy;
			dx=0;//rcNewWindowRect.left-rcOldWindowRect.left;
			dy=0;//_window_rect.top-rcOldWindowRect.top;
			if (!g_pfwFrames[i].floating)
			{
				if (g_pfwFrames[i].visible && !g_pfwFrames[i].needhide && !IsWindowVisible(g_pfwFrames[i].hWnd))
				{
					ShowWindow(g_pfwFrames[i].hWnd,SW_SHOW);
					if (g_pfwFrames[i].TitleBar.ShowTitleBar) ShowWindow(g_pfwFrames[i].TitleBar.hwnd,SW_SHOW);
				}
				if (g_pfwFrames[i].OwnerWindow && (INT_PTR)(g_pfwFrames[i].OwnerWindow)!=-2 )
				{
					if (!(mode&2))
					{
						HWND hwnd;
						hwnd=GetParent(g_pfwFrames[i].OwnerWindow);
						*PosBatch=DeferWindowPos(*PosBatch,g_pfwFrames[i].OwnerWindow,NULL,g_pfwFrames[i].wndSize.left+r->left,g_pfwFrames[i].wndSize.top+r->top,
							g_pfwFrames[i].wndSize.right-g_pfwFrames[i].wndSize.left, g_pfwFrames[i].wndSize.bottom-g_pfwFrames[i].wndSize.top,SWP_NOZORDER|SWP_NOACTIVATE);
						SetWindowPos(g_pfwFrames[i].hWnd,NULL,0,0,
							g_pfwFrames[i].wndSize.right-g_pfwFrames[i].wndSize.left, g_pfwFrames[i].wndSize.bottom-g_pfwFrames[i].wndSize.top,SWP_NOZORDER|SWP_NOACTIVATE/*|SWP_NOSENDCHANGING*/);
					}
					//Frame
					if(g_pfwFrames[i].TitleBar.ShowTitleBar)
					{
						SetWindowPos(g_pfwFrames[i].TitleBar.hwnd,NULL,g_pfwFrames[i].wndSize.left+dx,g_pfwFrames[i].wndSize.top-g_nTitleBarHeight-g_CluiData.nGapBetweenTitlebar+dy,
							g_pfwFrames[i].wndSize.right-g_pfwFrames[i].wndSize.left,g_nTitleBarHeight,SWP_NOZORDER|SWP_NOACTIVATE	);
						SetRect(&g_pfwFrames[i].TitleBar.wndSize,g_pfwFrames[i].wndSize.left,g_pfwFrames[i].wndSize.top-g_nTitleBarHeight-g_CluiData.nGapBetweenTitlebar,g_pfwFrames[i].wndSize.right,g_pfwFrames[i].wndSize.top-g_CluiData.nGapBetweenTitlebar);
						UpdateWindow(g_pfwFrames[i].TitleBar.hwnd);
					}
				}
				else
				{
					if(1)
					{
						int res=0;
						// set frame position
						res=SetWindowPos(g_pfwFrames[i].hWnd,NULL,g_pfwFrames[i].wndSize.left+dx,g_pfwFrames[i].wndSize.top+dy,
							g_pfwFrames[i].wndSize.right-g_pfwFrames[i].wndSize.left,
							g_pfwFrames[i].wndSize.bottom-g_pfwFrames[i].wndSize.top,SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSENDCHANGING);
					}
					if(1)
					{
						// set titlebar position
						if(g_pfwFrames[i].TitleBar.ShowTitleBar)
						{
							SetWindowPos(g_pfwFrames[i].TitleBar.hwnd,NULL,g_pfwFrames[i].wndSize.left+dx,g_pfwFrames[i].wndSize.top-g_nTitleBarHeight-g_CluiData.nGapBetweenTitlebar+dy,
								g_pfwFrames[i].wndSize.right-g_pfwFrames[i].wndSize.left,g_nTitleBarHeight,SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSENDCHANGING	);
							SetRect(&g_pfwFrames[i].TitleBar.wndSize,g_pfwFrames[i].wndSize.left,g_pfwFrames[i].wndSize.top-g_nTitleBarHeight-g_CluiData.nGapBetweenTitlebar,g_pfwFrames[i].wndSize.right,g_pfwFrames[i].wndSize.top-g_CluiData.nGapBetweenTitlebar);

						}
					}
					UpdateWindow(g_pfwFrames[i].hWnd);
					if(g_pfwFrames[i].TitleBar.ShowTitleBar) UpdateWindow(g_pfwFrames[i].TitleBar.hwnd);
				};
			}

		}
		if(GetTickCount()-_dwLastStoreTick>1000)
		{
			CLUIFramesStoreAllFrames();
			_dwLastStoreTick=GetTickCount();
		};
	}
	return 0;
}

int CheckFramesPos(RECT *wr)
{
	//CALLED only FROM MainWindow procedure at CLUI.c
	int i;
	if (_fCluiFramesModuleNotStarted) return -1;
	g_CluiData.nGapBetweenTitlebar=(int)db_get_dw(NULL,"CLUIFrames","GapBetweenTitleBar",SETTING_GAPTITLEBAR_DEFAULT);
	GapBetweenFrames=db_get_dw(NULL,"CLUIFrames","GapBetweenFrames",SETTING_GAPFRAMES_DEFAULT);

	for(i=0;i<g_nFramesCount;i++)
	{
		int dx;
		int dy;
		dx=0;//rcNewWindowRect.left-rcOldWindowRect.left;
		dy=0;//_window_rect.top-rcOldWindowRect.top;
		if (!g_pfwFrames[i].floating&&g_pfwFrames[i].visible)
		{
			if (!(g_pfwFrames[i].OwnerWindow && (INT_PTR)(g_pfwFrames[i].OwnerWindow)!=-2))
			{
				RECT r;
				GetWindowRect(g_pfwFrames[i].hWnd,&r);
				if (r.top-wr->top!=g_pfwFrames[i].wndSize.top ||r.left-wr->left!=g_pfwFrames[i].wndSize.left)
					SetWindowPos(g_pfwFrames[i].hWnd,NULL,g_pfwFrames[i].wndSize.left, g_pfwFrames[i].wndSize.top,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
			}
			if (g_pfwFrames[i].TitleBar.ShowTitleBar)
			{
				RECT r;
				GetWindowRect(g_pfwFrames[i].TitleBar.hwnd,&r);
				if (r.top-wr->top!=g_pfwFrames[i].wndSize.top-g_nTitleBarHeight-g_CluiData.nGapBetweenTitlebar || r.left-wr->left!=g_pfwFrames[i].wndSize.left)
				{
					SetWindowPos(g_pfwFrames[i].TitleBar.hwnd,NULL,g_pfwFrames[i].wndSize.left+dx,g_pfwFrames[i].wndSize.top-g_nTitleBarHeight-g_CluiData.nGapBetweenTitlebar+dy,
						g_pfwFrames[i].wndSize.right-g_pfwFrames[i].wndSize.left,g_nTitleBarHeight,SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE);
					SetRect(&g_pfwFrames[i].TitleBar.wndSize,g_pfwFrames[i].wndSize.left,g_pfwFrames[i].wndSize.top-g_nTitleBarHeight-g_CluiData.nGapBetweenTitlebar,g_pfwFrames[i].wndSize.right,g_pfwFrames[i].wndSize.top-g_CluiData.nGapBetweenTitlebar);
				}
			}
		}
	}

	return 0;
}

int CLUIFramesOnClistResize(WPARAM wParam,LPARAM lParam)
{
	RECT nRect;
	int tick;
	GapBetweenFrames=db_get_dw(NULL,"CLUIFrames","GapBetweenFrames",SETTING_GAPFRAMES_DEFAULT);
	g_CluiData.nGapBetweenTitlebar=db_get_dw(NULL,"CLUIFrames","GapBetweenTitleBar",SETTING_GAPTITLEBAR_DEFAULT);

	if (_fCluiFramesModuleNotStarted) return -1;

	//need to enlarge parent
	{
		RECT mainRect;
		int mainHeight, minHeight;
		GetWindowRect(pcli->hwndContactList,&mainRect);
		mainHeight=mainRect.bottom-mainRect.top;
		minHeight=CLUIFrames_GetTotalHeight();
		if (mainHeight<minHeight)
		{
			BOOL Upward=FALSE;
			Upward=!g_CluiData.fDocked && g_CluiData.fAutoSize&&db_get_b(NULL,"CLUI","AutoSizeUpward",SETTING_AUTOSIZEUPWARD_DEFAULT);

			if (Upward)
				mainRect.top=mainRect.bottom-minHeight;
			else
				mainRect.bottom=mainRect.top+minHeight;
			SetWindowPos(pcli->hwndContactList,NULL,mainRect.left,mainRect.top,mainRect.right-mainRect.left, mainRect.bottom-mainRect.top, SWP_NOZORDER|SWP_NOREDRAW|SWP_NOACTIVATE|SWP_NOSENDCHANGING);
		}
		GetWindowRect(pcli->hwndContactList,&mainRect);
		mainHeight=mainRect.bottom-mainRect.top;
		//if (mainHeight<minHeight)
		//	  DebugBreak();
	}
	GetClientRect(pcli->hwndContactList,&nRect);
	//$$$ Fixed borders
	if (lParam && lParam!=1 && lParam!=2)
	{
		RECT oldRect;
		POINT pt;
		RECT * newRect=(RECT *)lParam;
		int dl,dt,dr,db;
		GetWindowRect((HWND)wParam,&oldRect);
		pt.x=nRect.left;
		pt.y=nRect.top;
		ClientToScreen(pcli->hwndContactList,&pt);
		dl=pt.x-oldRect.left;
		dt=pt.y-oldRect.top;
		dr=(oldRect.right-oldRect.left)-(nRect.right-nRect.left)-dl;
		db=(oldRect.bottom-oldRect.top)-(nRect.bottom-nRect.top)-dt;
		nRect.left=newRect->left+dl;
		nRect.top=newRect->top+dt;
		nRect.bottom=newRect->bottom-db;
		nRect.right=newRect->right-dr;
	}


	//if(DBGetContactSettingByte(NULL,"CLUI","ShowSBar",SETTING_SHOWSBAR_DEFAULT))GetWindowRect(pcli->hwndStatus,&rcStatus);
	//else rcStatus.top=rcStatus.bottom=0;
	// nRect.top--;
	/* $$$	rcStatus.top=rcStatus.bottom=0;


	nRect.bottom-=nRect.top;
	nRect.bottom-=(rcStatus.bottom-rcStatus.top);
	nRect.right-=nRect.left;
	nRect.left=0;
	nRect.top=0;
	ContactListHeight=nRect.bottom; $$$*/

	nRect.left+=g_CluiData.LeftClientMargin;
	nRect.right-=g_CluiData.RightClientMargin;
	nRect.top+=g_CluiData.TopClientMargin;
	nRect.bottom-=g_CluiData.BottomClientMargin;

	if (nRect.bottom<nRect.top)
		nRect.bottom=nRect.top;
	_nContactListHeight=nRect.bottom-nRect.top; //$$

	tick=GetTickCount();


	CLUIFramesResize(nRect);

	CLUIFrames_ApplyNewSizes(2);
	CLUIFrames_ApplyNewSizes(1);

	//resizing=FALSE;

	tick=GetTickCount()-tick;

	if (pcli->hwndContactList!=0) CLUI__cliInvalidateRect(pcli->hwndContactList,NULL,TRUE);
	if (pcli->hwndContactList!=0) UpdateWindow(pcli->hwndContactList);

	if(lParam==2) RedrawWindow(pcli->hwndContactList,NULL,NULL,RDW_UPDATENOW|RDW_ALLCHILDREN|RDW_ERASE|RDW_INVALIDATE);


	Sleep(0);

	//dont save to database too many times
	if(GetTickCount()-_dwLastStoreTick>1000){ CLUIFramesStoreAllFrames();_dwLastStoreTick=GetTickCount();};

	return 0;
}

int OnFrameTitleBarBackgroundChange(WPARAM wParam,LPARAM lParam)
{
	if (MirandaExiting()) return 0;
	{
		DBVARIANT dbv={0};

		AlignCOLLIconToLeft=db_get_b(NULL,"FrameTitleBar","AlignCOLLIconToLeft",CLCDEFAULT_COLLICONTOLEFT);

		bkColour=sttGetColor("FrameTitleBar","BkColour",CLCDEFAULT_BKCOLOUR);
		bkUseWinColours=db_get_b(NULL,"FrameTitleBar","UseWinColours",CLCDEFAULT_USEWINDOWSCOLOURS);
		SelBkColour=sttGetColor("FrameTitleBar","TextColour",CLCDEFAULT_TEXTCOLOUR);
		if(hBmpBackground) {DeleteObject(hBmpBackground); hBmpBackground=NULL;}
		if (g_CluiData.fDisableSkinEngine)
		{
			if(db_get_b(NULL,"FrameTitleBar","UseBitmap",CLCDEFAULT_USEBITMAP)) {
				if (!DBGetContactSettingString(NULL,"FrameTitleBar","BkBitmap",&dbv)) {
					hBmpBackground=(HBITMAP)CallService(MS_UTILS_LOADBITMAP,0,(LPARAM)dbv.pszVal);
					//mir_free_and_nill(dbv.pszVal);
					db_free(&dbv);
				}
			}
			backgroundBmpUse=db_get_w(NULL,"FrameTitleBar","BkBmpUse",CLCDEFAULT_BKBMPUSE);
		}
	};

	CLUI__cliInvalidateRect( pcli->hwndContactList, 0, 0 );

	RedrawWindow(pcli->hwndContactList,NULL,NULL,RDW_UPDATENOW|RDW_ALLCHILDREN|RDW_ERASE|RDW_INVALIDATE);

	return 0;
}

void DrawBackGround(HWND hwnd,HDC mhdc, HBITMAP hBmpBackground, COLORREF bkColour, DWORD backgroundBmpUse )
{
	HDC hdcMem,hdc;
	RECT clRect,*rcPaint;

	int yScroll=0;
	int y;
	PAINTSTRUCT paintst={0};
	HBITMAP hBmpOsb,hOldBmp;
	DWORD style=GetWindowLongPtr(hwnd,GWL_STYLE);
	int grey=0;
	HFONT oFont;
	HBRUSH hBrushAlternateGrey=NULL;

	HFONT hFont;

	//InvalidateRect(hwnd,0,FALSE);

	hFont=(HFONT)SendMessage(hwnd,WM_GETFONT,0,0);

	if (mhdc)
	{
		hdc=mhdc;
		rcPaint=NULL;
	}
	else
	{
		hdc=BeginPaint(hwnd,&paintst);
		rcPaint=&(paintst.rcPaint);
	}

	GetClientRect(hwnd,&clRect);
	if(rcPaint==NULL) rcPaint=&clRect;
	if (rcPaint->right-rcPaint->left==0||rcPaint->top-rcPaint->bottom==0) rcPaint=&clRect;
	y=-yScroll;
	hdcMem=CreateCompatibleDC(hdc);
	hBmpOsb=CreateBitmap(clRect.right,clRect.bottom,1,GetDeviceCaps(hdc,BITSPIXEL),NULL);
	hOldBmp=(HBITMAP)SelectObject(hdcMem,hBmpOsb);
	oFont=(HFONT)SelectObject(hdcMem,hFont);
	SetBkMode(hdcMem,TRANSPARENT);
	SetStretchBltMode(hdcMem,HALFTONE);
	{	HBRUSH hBrush;

	hBrush=CreateSolidBrush(bkColour);
	FillRect(hdcMem,rcPaint,hBrush);
	DeleteObject(hBrush);
	if(hBmpBackground) {
		BITMAP bmp;
		HDC hdcBmp;
		int x,y;
		int maxx,maxy;
		int destw,desth;

		GetObject(hBmpBackground,sizeof(bmp),&bmp);
		hdcBmp=CreateCompatibleDC(hdcMem);
		SelectObject(hdcBmp,hBmpBackground);
		y=backgroundBmpUse&CLBF_SCROLL?-yScroll:0;
		maxx=backgroundBmpUse&CLBF_TILEH?clRect.right:1;
		maxy=backgroundBmpUse&CLBF_TILEV?maxy=rcPaint->bottom:y+1;
		switch(backgroundBmpUse&CLBM_TYPE) {
				case CLB_STRETCH:
					if(backgroundBmpUse&CLBF_PROPORTIONAL) {
						if(clRect.right*bmp.bmHeight<clRect.bottom*bmp.bmWidth) {
							desth=clRect.bottom;
							destw=desth*bmp.bmWidth/bmp.bmHeight;
						}
						else {
							destw=clRect.right;
							desth=destw*bmp.bmHeight/bmp.bmWidth;
						}
					}
					else {
						destw=clRect.right;
						desth=clRect.bottom;
					}
					break;
				case CLB_STRETCHH:
					if(backgroundBmpUse&CLBF_PROPORTIONAL) {
						destw=clRect.right;
						desth=destw*bmp.bmHeight/bmp.bmWidth;
					}
					else {
						destw=clRect.right;
						desth=bmp.bmHeight;
					}
					break;
				case CLB_STRETCHV:
					if(backgroundBmpUse&CLBF_PROPORTIONAL) {
						desth=clRect.bottom;
						destw=desth*bmp.bmWidth/bmp.bmHeight;
					}
					else {
						destw=bmp.bmWidth;
						desth=clRect.bottom;
					}
					break;
				default:    //clb_topleft
					destw=bmp.bmWidth;
					desth=bmp.bmHeight;
					break;
		}
		desth=clRect.bottom -clRect.top;
		for (;y<maxy;y+=desth) {
			if(y<rcPaint->top-desth) continue;
			for(x=0;x<maxx;x+=destw)
				StretchBlt(hdcMem,x,y,destw,desth,hdcBmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
		}
		DeleteDC(hdcBmp);
	}
	}

	{

		BitBlt(hdc,rcPaint->left,rcPaint->top,rcPaint->right-rcPaint->left,rcPaint->bottom-rcPaint->top,hdcMem,rcPaint->left,rcPaint->top,SRCCOPY);

		SelectObject(hdcMem,hOldBmp);
		SelectObject(hdcMem,oFont);
		DeleteObject(hBmpOsb);
		DeleteDC(hdcMem);
		paintst.fErase=FALSE;
		//DeleteObject(hFont);
		if (!mhdc)
		{
			EndPaint(hwnd,&paintst);
		}
	}
}


int DrawTitleBar(HDC hdcMem2,RECT * rect,int Frameid)
{
	int pos;
	BOOL bThemed=FALSE;
	HDC hdcMem;
	HFONT hoTTBFont;
	RECT rc=*rect;
	HBRUSH hBack,hoBrush;
	HBITMAP b1=NULL,b2=NULL;
	hdcMem=CreateCompatibleDC(hdcMem2);

	SetBkMode(hdcMem,TRANSPARENT);
	hoTTBFont=(HFONT)SelectObject(hdcMem,_hTitleBarFont);
	ske_ResetTextEffect(hdcMem);
	ske_ResetTextEffect(hdcMem2);
	hBack=GetSysColorBrush(COLOR_3DFACE);
	hoBrush=(HBRUSH)SelectObject(hdcMem,hBack);

	pos=id2pos(Frameid);

	if (pos>=0&&pos<g_nFramesCount)
	{
		GetClientRect(g_pfwFrames[pos].TitleBar.hwnd,&rc);
		if (g_pfwFrames[pos].floating)
		{

			rc.bottom=rc.top+g_nTitleBarHeight;
			g_pfwFrames[pos].TitleBar.wndSize=rc;
		}
		else
		{
			g_pfwFrames[pos].TitleBar.wndSize=rc;
		}
		b1=ske_CreateDIB32(rc.right-rc.left,rc.bottom-rc.top);
		b2=(HBITMAP)SelectObject(hdcMem,b1);
		if ( g_pfwFrames[pos].floating && !g_CluiData.fDisableSkinEngine)
		{
			FillRect(hdcMem,&rc,hBack);
			//SelectObject(hdcMem,hoBrush);
			SkinDrawGlyph(hdcMem,&rc,&rc,"Main,ID=FrameCaption");
		}
		else
		{
			if (g_CluiData.fDisableSkinEngine)
			{
				if (!hBmpBackground && bkUseWinColours && xpt_IsThemed(_hFrameTitleTheme))
				{
				   int state=CS_ACTIVE;
				  // if (GetForegroundWindow()!=pcli->hwndContactList) state=CS_INACTIVE;
				   xpt_DrawThemeBackground(_hFrameTitleTheme,hdcMem, WP_SMALLCAPTION, state, &rc,&rc);
				   bThemed=TRUE;
				}
				else
                   DrawBackGround(g_pfwFrames[pos].TitleBar.hwnd,hdcMem, hBmpBackground, bkColour, backgroundBmpUse);
			}
			else if (!g_CluiData.fLayered)
			{
				ske_BltBackImage(g_pfwFrames[pos].TitleBar.hwnd,hdcMem,&rc);
			}
			else  BitBlt(hdcMem,0,0,rc.right-rc.left,rc.bottom-rc.top,hdcMem2,rect->left,rect->top,SRCCOPY);
			SkinDrawGlyph(hdcMem,&rc,&rc,"Main,ID=FrameCaption");
		}
		if (bThemed)
			SetTextColor(hdcMem,GetSysColor(COLOR_CAPTIONTEXT ));
		else
			SetTextColor(hdcMem,SelBkColour);
		{
			RECT textrc=rc;
			if (!AlignCOLLIconToLeft)
			{

				if(g_pfwFrames[pos].TitleBar.hicon!=NULL)
				{
					mod_DrawIconEx_helper(hdcMem,rc.left +2,rc.top+((g_nTitleBarHeight>>1)-(GetSystemMetrics(SM_CYSMICON)>>1)),g_pfwFrames[pos].TitleBar.hicon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL);
					textrc.left+=GetSystemMetrics(SM_CXSMICON)+4;
					textrc.top+=2;
				}
				else
				{
					textrc.left+=2;
					textrc.top+=2;
				}

			}
			else
			{
				textrc.left+=GetSystemMetrics(SM_CXSMICON)+2;
				textrc.top+=2;
			}
			ske_TextOut(hdcMem,textrc.left,textrc.top,g_pfwFrames[pos].TitleBar.tbname,lstrlen(g_pfwFrames[pos].TitleBar.tbname));

		}
		if (!AlignCOLLIconToLeft)
		{
			mod_DrawIconEx_helper(hdcMem,g_pfwFrames[pos].TitleBar.wndSize.right-GetSystemMetrics(SM_CXSMICON)-2,rc.top+((g_nTitleBarHeight>>1)-(GetSystemMetrics(SM_CXSMICON)>>1)),g_pfwFrames[pos].collapsed?LoadSkinnedIcon(SKINICON_OTHER_GROUPOPEN):LoadSkinnedIcon(SKINICON_OTHER_GROUPSHUT),GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL);
		}
		else
		{
			mod_DrawIconEx_helper(hdcMem,rc.left,rc.top+((g_nTitleBarHeight>>1)-(GetSystemMetrics(SM_CXSMICON)>>1)),g_pfwFrames[pos].collapsed?LoadSkinnedIcon(SKINICON_OTHER_GROUPOPEN):LoadSkinnedIcon(SKINICON_OTHER_GROUPSHUT),GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL);
		}


	}
	{
		BLENDFUNCTION bf={AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
		if (g_pfwFrames[pos].floating || (!g_CluiData.fLayered))
		{
			HRGN rgn=CreateRectRgn(rect->left,rect->top,rect->right,rect->bottom);
			SelectClipRgn(hdcMem2,rgn);
			BitBlt(hdcMem2,rect->left,rect->top,rc.right-rc.left,rc.bottom-rc.top,hdcMem,0,0,SRCCOPY);
			DeleteObject(rgn);
		}
		else
			BitBlt(hdcMem2,rect->left,rect->top,rc.right-rc.left,rc.bottom-rc.top,hdcMem,0,0,SRCCOPY);
		//MyAlphaBlend(hdcMem2,rect.left,rect.top,rc.right-rc.left,rc.bottom-rc.top,hdcMem,0,0,rc.right-rc.left,rc.bottom-rc.top,bf);
	}

	SelectObject(hdcMem,b2);
	DeleteObject(b1);
	SelectObject(hdcMem,hoTTBFont);
	SelectObject(hdcMem,hoBrush);
	mod_DeleteDC(hdcMem);
	return 0;
}
static LRESULT CALLBACK CLUIFrameTitleBarProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	static int s_nLastByPos			= -1;
	static int s_nOldFrameHeight	= -1;
	static int s_nCurDragBar		= -1;

	RECT rect;
	int Frameid,Framemod,direction;
	int xpos,ypos;

	Frameid=(GetWindowLongPtr(hwnd,GWLP_USERDATA));
	memset(&rect,0,sizeof(rect));


	switch(msg)
	{
	case WM_CREATE:
		if (!_hFrameTitleTheme)
		   _hFrameTitleTheme=xpt_AddThemeHandle(hwnd,L"WINDOW");
		SendMessage(hwnd,WM_SETFONT,(WPARAM)_hTitleBarFont,0);
		return FALSE;
	case WM_MEASUREITEM:
		return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam);
	case WM_DRAWITEM:
		return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam);
	case WM_USER+100:
		return 1;
	case WM_ENABLE:
		if (hwnd!=0) CLUI__cliInvalidateRect(hwnd,NULL,FALSE);
		return 0;
	case WM_ERASEBKGND:
		{
			return 1;
		}
	case WM_COMMAND:


		if (ServiceExists(MO_CREATENEWMENUOBJECT))
		{
			//if ( CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wParam),0),(LPARAM)Frameid)){break;};
			if (ProcessCommandProxy(MAKEWPARAM(LOWORD(wParam),0),(LPARAM)Frameid)) break;
		}else
		{
			if ( CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wParam),MPCF_CONTEXTFRAMEMENU),(LPARAM)Frameid)){break;};

		};


		if(HIWORD(wParam)==0) {//mouse events for self created menu
			int framepos=id2pos(Frameid);
			if (framepos==-1){break;};

			switch(LOWORD(wParam))
			{
			case frame_menu_lock:
				g_pfwFrames[framepos].Locked=!g_pfwFrames[framepos].Locked;
				break;
			case frame_menu_visible:
				g_pfwFrames[framepos].visible=!g_pfwFrames[framepos].visible;
				break;
			case frame_menu_showtitlebar:
				g_pfwFrames[framepos].TitleBar.ShowTitleBar=!g_pfwFrames[framepos].TitleBar.ShowTitleBar;
				break;
			case frame_menu_floating:
				CLUIFrames_SetFrameFloat(Frameid,0);
				break;
			}
			CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
		}

		break;
	case WM_RBUTTONDOWN:
		{
			HMENU hmenu;
			POINT pt;
			GetCursorPos(&pt);

			if (ServiceExists(MS_CLIST_MENUBUILDFRAMECONTEXT))
			{
				hmenu=(HMENU)CallService(MS_CLIST_MENUBUILDFRAMECONTEXT,Frameid,0);
			}
			else
			{//legacy menu support
				int framepos=id2pos(Frameid);

				if (framepos==-1){break;};
				hmenu=CreatePopupMenu();
				//				Frames[Frameid].TitleBar.hmenu=hmenu;
				AppendMenu(hmenu,MF_STRING|MF_DISABLED|MF_GRAYED,15,g_pfwFrames[framepos].Name);
				AppendMenu(hmenu,MF_SEPARATOR,16,_T(""));

				if (g_pfwFrames[framepos].Locked)
				{AppendMenu(hmenu,MF_STRING|MF_CHECKED,frame_menu_lock,TranslateT("Lock Frame"));}
				else{AppendMenu(hmenu,MF_STRING,frame_menu_lock,TranslateT("Lock Frame"));};

				if (g_pfwFrames[framepos].visible)
				{AppendMenu(hmenu,MF_STRING|MF_CHECKED,frame_menu_visible,TranslateT("Visible"));}
				else{AppendMenu(hmenu,MF_STRING,frame_menu_visible,TranslateT("Visible"));};

				if (g_pfwFrames[framepos].TitleBar.ShowTitleBar)
				{AppendMenu(hmenu,MF_STRING|MF_CHECKED,frame_menu_showtitlebar,TranslateT("Show TitleBar"));}
				else{AppendMenu(hmenu,MF_STRING,frame_menu_showtitlebar,TranslateT("Show TitleBar"));};

				if (g_pfwFrames[framepos].floating)
				{AppendMenu(hmenu,MF_STRING|MF_CHECKED,frame_menu_floating,TranslateT("Floating"));}
				else{AppendMenu(hmenu,MF_STRING,frame_menu_floating,TranslateT("Floating"));};

				//err=GetMenuItemCount(hmenu)

			};

			TrackPopupMenu(hmenu,TPM_LEFTALIGN,pt.x,pt.y,0,hwnd,0);
			DestroyMenu(hmenu);
		}
		break;
	case WM_LBUTTONDBLCLK:
		{
			Framemod=-1;
			s_nLastByPos=-1;s_nOldFrameHeight=-1;ReleaseCapture();
			CallService(MS_CLIST_FRAMES_UCOLLFRAME,Frameid,0);
			s_nLastByPos=-1;s_nOldFrameHeight=-1;ReleaseCapture();
		}
		break;

	case WM_LBUTTONUP:
		{
			if(GetCapture()!=hwnd){break;};
			s_nCurDragBar=-1;s_nLastByPos=-1;s_nOldFrameHeight=-1;ReleaseCapture();
			break;
		};
	case WM_LBUTTONDOWN:
		{

			int framepos=id2pos(Frameid);

			if (framepos==-1){break;};
			{
				if (g_pfwFrames[framepos].floating)
				{

					POINT pt;
					GetCursorPos(&pt);
					g_pfwFrames[framepos].TitleBar.oldpos=pt;
				};
			};

			//ScreenToClient(Frames[framepos].ContainerWnd,&Frames[framepos].TitleBar.oldpos);

			if ((!(wParam&MK_CONTROL))&&g_pfwFrames[framepos].Locked&&(!(g_pfwFrames[framepos].floating)))
			{
				if (db_get_b(NULL,"CLUI","ClientAreaDrag",SETTING_CLIENTDRAG_DEFAULT)) {
					POINT pt;
					int res;
					//pt=nm->pt;
					GetCursorPos(&pt);
					res=SendMessage(GetParent(hwnd), WM_SYSCOMMAND, SC_MOVE|HTCAPTION,MAKELPARAM(pt.x,pt.y));
					return res;
				}
			};

			if (g_pfwFrames[framepos].floating)
			{
				RECT rc;
				GetCursorPos(&ptOld);
				//ClientToScreen(hwnd,&ptOld);
				GetWindowRect( hwnd, &rc );

				nLeft	= (short)rc.left;
				nTop	= (short)rc.top;
			};

			SetCapture(hwnd);


			break;
		};
	case WM_MOUSEMOVE:
		{
			POINT pt,pt2;
			RECT wndr;
			int pos;
			//tbinfo
			{
				char TBcapt[255];


				pos=id2pos(Frameid);

				if (pos!=-1)
				{
					int oldflags;


					sprintf(TBcapt,"%s - h:%d, vis:%d, fl:%d, fl:(%d,%d,%d,%d),or: %d",
						g_pfwFrames[pos].szName,g_pfwFrames[pos].height,g_pfwFrames[pos].visible,g_pfwFrames[pos].floating,
						g_pfwFrames[pos].FloatingPos.x,g_pfwFrames[pos].FloatingPos.y,
						g_pfwFrames[pos].FloatingSize.x,g_pfwFrames[pos].FloatingSize.y,
						g_pfwFrames[pos].order
						);

					oldflags=CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS,MAKEWPARAM(FO_FLAGS,g_pfwFrames[pos].id),(LPARAM)0);
					if (!(oldflags&F_SHOWTBTIP))
					{
						oldflags|=F_SHOWTBTIP;
						//CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_FLAGS,Frames[pos].id),(LPARAM)oldflags);
					};
					//CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_TBTIPNAME,Frames[pos].id),(LPARAM)TBcapt);
				};



			}
			//
			if ((wParam&MK_LBUTTON)/*&&(wParam&MK_CONTROL)*/)
			{
				RECT rcMiranda;
				RECT rcwnd,rcOverlap;
				POINT newpt,ofspt,curpt,newpos;
				//if(GetCapture()!=hwnd){break;};
				//curdragbar=-1;lbypos=-1;oldframeheight=-1;ReleaseCapture();

				pos=id2pos(Frameid);
				if (g_pfwFrames[pos].floating)
				{

					GetCursorPos(&curpt);
					rcwnd.bottom=curpt.y+5;
					rcwnd.top=curpt.y;
					rcwnd.left=curpt.x;
					rcwnd.right=curpt.x+5;

					GetWindowRect(pcli->hwndContactList, &rcMiranda );
					//GetWindowRect( Frames[pos].ContainerWnd, &rcwnd );
					//IntersectRect( &rcOverlap, &rcwnd, &rcMiranda )
					if (IsWindowVisible(pcli->hwndContactList) &&IntersectRect( &rcOverlap, &rcwnd, &rcMiranda ))
					{
						int id=g_pfwFrames[pos].id;




						ofspt.x=0;ofspt.y=0;
						ClientToScreen(g_pfwFrames[pos].TitleBar.hwnd,&ofspt);
						ofspt.x=curpt.x-ofspt.x;ofspt.y=curpt.y-ofspt.y;

						CLUIFrames_SetFrameFloat(id,0);
						newpt.x=0;newpt.y=0;
						ClientToScreen(g_pfwFrames[pos].TitleBar.hwnd,&newpt);
						SetCursorPos(newpt.x+ofspt.x,newpt.y+ofspt.y);
						GetCursorPos(&curpt);

						g_pfwFrames[pos].TitleBar.oldpos=curpt;

						return(0);
					};

				}
				else
				{
					int id=g_pfwFrames[pos].id;

					GetCursorPos(&curpt);
					rcwnd.bottom=curpt.y+5;
					rcwnd.top=curpt.y;
					rcwnd.left=curpt.x;
					rcwnd.right=curpt.x+5;

					GetWindowRect(pcli->hwndContactList, &rcMiranda );
					//GetWindowRect( Frames[pos].ContainerWnd, &rcwnd );
					//IntersectRect( &rcOverlap, &rcwnd, &rcMiranda )


					if (!IntersectRect( &rcOverlap, &rcwnd, &rcMiranda ))
					{
						GetCursorPos(&curpt);
						GetWindowRect( g_pfwFrames[pos].hWnd, &rcwnd );
						rcwnd.left=rcwnd.right-rcwnd.left;
						rcwnd.top=rcwnd.bottom-rcwnd.top;
						newpos.x=curpt.x;newpos.y=curpt.y;
						if (curpt.x>=(rcMiranda.right-1)){newpos.x=curpt.x+5;};
						if (curpt.x<=(rcMiranda.left+1)){newpos.x=curpt.x-(rcwnd.left)-5;};
						if (curpt.y>=(rcMiranda.bottom-1)){newpos.y=curpt.y+5;};
						if (curpt.y<=(rcMiranda.top+1)){newpos.y=curpt.y-(rcwnd.top)-5;};
						ofspt.x=0;ofspt.y=0;
						//ClientToScreen(Frames[pos].TitleBar.hwnd,&ofspt);
						GetWindowRect(g_pfwFrames[pos].TitleBar.hwnd,&rcwnd);
						ofspt.x=curpt.x-ofspt.x;ofspt.y=curpt.y-ofspt.y;

						g_pfwFrames[pos].FloatingPos.x=newpos.x;
						g_pfwFrames[pos].FloatingPos.y=newpos.y;
						CLUIFrames_SetFrameFloat(id,0);
						//SetWindowPos(Frames[pos].ContainerWnd,0,newpos.x,newpos.y,0,0,SWP_NOSIZE);


						newpt.x=0;newpt.y=0;
						ClientToScreen(g_pfwFrames[pos].TitleBar.hwnd,&newpt);

						GetWindowRect( g_pfwFrames[pos].hWnd, &rcwnd );
						SetCursorPos(newpt.x+(rcwnd.right-rcwnd.left)/2,newpt.y+(rcwnd.bottom-rcwnd.top)/2);
						GetCursorPos(&curpt);

						g_pfwFrames[pos].TitleBar.oldpos=curpt;


						return(0);
					};

				};

				//return(0);
			};

			if(wParam&MK_LBUTTON) {
				int newh=-1,prevold;

				if(GetCapture()!=hwnd){break;};


				pos=id2pos(Frameid);

				if (g_pfwFrames[pos].floating)
				{
					GetCursorPos(&pt);
					if ((g_pfwFrames[pos].TitleBar.oldpos.x!=pt.x)||(g_pfwFrames[pos].TitleBar.oldpos.y!=pt.y))
					{

						pt2=pt;
						ScreenToClient(hwnd,&pt2);
						GetWindowRect(g_pfwFrames[pos].ContainerWnd,&wndr);
						{
							int dX,dY;
							POINT ptNew;

							ptNew.x = pt.x;
							ptNew.y = pt.y;
							//ClientToScreen( hwnd, &ptNew );

							dX = ptNew.x - ptOld.x;
							dY = ptNew.y - ptOld.y;

							nLeft	+= (short)dX;
							nTop	+= (short)dY;

							if (!(wParam&MK_CONTROL))
							{
								PositionThumb( &g_pfwFrames[pos], nLeft, nTop );
							}else
							{

								SetWindowPos(	g_pfwFrames[pos].ContainerWnd,
									HWND_TOPMOST,
									nLeft,
									nTop,
									0,
									0,
									SWP_NOSIZE |SWP_NOACTIVATE| SWP_NOZORDER );
							};

							ptOld = ptNew;



						}

						pt.x=nLeft;
						pt.y=nTop;
						g_pfwFrames[pos].TitleBar.oldpos=pt;
					};

					//break;
					return(0);
				};


				if(g_pfwFrames[pos].prevvisframe!=-1) {
					GetCursorPos(&pt);

					if ((g_pfwFrames[pos].TitleBar.oldpos.x==pt.x)&&(g_pfwFrames[pos].TitleBar.oldpos.y==pt.y))
					{break;};

					ypos=rect.top+pt.y;xpos=rect.left+pt.x;
					Framemod=-1;

					if(g_pfwFrames[pos].align==alBottom)	{
						direction=-1;
						Framemod=pos;
					}
					else {
						direction=1;
						Framemod=g_pfwFrames[pos].prevvisframe;
					}
					if(g_pfwFrames[Framemod].Locked) {break;};
					if(s_nCurDragBar!=-1&&s_nCurDragBar!=pos) {break;};

					if(s_nLastByPos==-1) {
						s_nCurDragBar=pos;
						s_nLastByPos=ypos;
						s_nOldFrameHeight=g_pfwFrames[Framemod].height;
						SetCapture(hwnd);
						{break;};
					}
					else
					{
						//	if(GetCapture()!=hwnd){break;};
					};

					newh=s_nOldFrameHeight+direction*(ypos-s_nLastByPos);
					if(newh>0)	{
						prevold=g_pfwFrames[Framemod].height;
						g_pfwFrames[Framemod].height=newh;
						if (!CLUIFramesFitInSize()) { g_pfwFrames[Framemod].height=prevold; return TRUE;}
						g_pfwFrames[Framemod].height=newh;
						if(newh>3) g_pfwFrames[Framemod].collapsed=TRUE;

					}
					g_pfwFrames[pos].TitleBar.oldpos=pt;
				}

				if (newh>0)
				{
					CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
				};
				break;
			}
			s_nCurDragBar=-1;s_nLastByPos=-1;s_nOldFrameHeight=-1;ReleaseCapture();
		}
		break;
	case WM_PRINT:
	case WM_PRINTCLIENT:
		{
			//if (lParam&PRF_CLIENT)
			{
				GetClientRect(hwnd,&rect);
				if (!g_CluiData.fLayered)
				{
					ske_BltBackImage(hwnd,(HDC)wParam,&rect);
				}
				DrawTitleBar((HDC)wParam,&rect,Frameid);
			}
			break;
		}
	case WM_SIZE:
		{
			InvalidateRect(hwnd,NULL,FALSE);
			return DefWindowProc(hwnd, msg, wParam, lParam);
		}
	case WM_PAINT:
		{
			HDC paintDC;
			if (g_pfwFrames[id2pos(Frameid)].floating || (!g_CluiData.fLayered))
			{
				GetClientRect(hwnd,&rect);
				paintDC = GetDC(hwnd);
				DrawTitleBar(paintDC,&rect,Frameid);
				ReleaseDC(hwnd,paintDC);
				ValidateRect(hwnd,NULL);

			}
			return DefWindowProc(hwnd, msg, wParam, lParam);
		}
	default:return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return TRUE;
}
static int CLUIFrameResizeFloatingFrame(int framepos)
{

	int width,height;
	RECT rect;

	if (!g_pfwFrames[framepos].floating){return(0);};
	if (g_pfwFrames[framepos].ContainerWnd==0){return(0);};
	GetClientRect(g_pfwFrames[framepos].ContainerWnd,&rect);

	width=rect.right-rect.left;
	height=rect.bottom-rect.top;

	g_pfwFrames[framepos].visible?CLUI_ShowWindowMod(g_pfwFrames[framepos].ContainerWnd,SW_SHOW/*NOACTIVATE*/):CLUI_ShowWindowMod(g_pfwFrames[framepos].ContainerWnd,SW_HIDE);



	if (g_pfwFrames[framepos].TitleBar.ShowTitleBar)
	{
		CLUI_ShowWindowMod(g_pfwFrames[framepos].TitleBar.hwnd,SW_SHOW/*NOACTIVATE*/);
		//if (Frames[framepos].Locked){return(0);};
		g_pfwFrames[framepos].height=height-DEFAULT_TITLEBAR_HEIGHT;

		SetWindowPos(g_pfwFrames[framepos].TitleBar.hwnd,HWND_TOP,0,0,width,DEFAULT_TITLEBAR_HEIGHT,SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_DRAWFRAME);
		SetWindowPos(g_pfwFrames[framepos].hWnd,HWND_TOP,0,DEFAULT_TITLEBAR_HEIGHT,width,height-DEFAULT_TITLEBAR_HEIGHT,SWP_SHOWWINDOW);

	}
	else
	{
		//SetWindowPos(Frames[framepos].TitleBar.hwnd,HWND_TOP,0,0,width,DEFAULT_TITLEBAR_HEIGHT,SWP_SHOWWINDOW|SWP_NOMOVE);
		//if (Frames[framepos].Locked){return(0);};
		g_pfwFrames[framepos].height=height;
		CLUI_ShowWindowMod(g_pfwFrames[framepos].TitleBar.hwnd,SW_HIDE);
		SetWindowPos(g_pfwFrames[framepos].hWnd,HWND_TOP,0,0,width,height,SWP_SHOWWINDOW|SWP_NOACTIVATE);

	};
	//			CLUIFramesForceUpdateFrame(&Frames[framepos]);
	if (g_pfwFrames[framepos].ContainerWnd!=0) UpdateWindow(g_pfwFrames[framepos].ContainerWnd);
	//GetClientRect(Frames[framepos].TitleBar.hwnd,&Frames[framepos].TitleBar.wndSize);
	GetWindowRect(g_pfwFrames[framepos].hWnd,&g_pfwFrames[framepos].wndSize);
	//Frames[framepos].height=Frames[framepos].wndSize.bottom-Frames[framepos].wndSize.top;
	//GetClientRect(Frames[framepos].hWnd,&Frames[framepos].wndSize);
	//Frames[framepos].height=Frames[framepos].wndSize.bottom-Frames[framepos].wndSize.top;
	return(0);
};

static int CLUIFrameOnMainMenuBuild(WPARAM wParam,LPARAM lParam)
{
	if (MirandaExiting()) return 0;
	CLUIFramesLoadMainMenu();

	return 0;
}

static LRESULT CALLBACK CLUIFrameSubContainerProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

	RECT rect;
	int Frameid;

	Frameid=(GetWindowLongPtr(hwnd,GWLP_USERDATA));
	memset(&rect,0,sizeof(rect));

	/*
	if ((msg == WM_MOVE) || (msg == WM_MOVING) || (msg == WM_NCLBUTTONDOWN) || (msg == WM_SYSCOMMAND)  )
	{
	if (ServiceExists("Utils/SnapWindowProc"))
	{
	SnapWindowProc_t SnapInfo;
	memset(&SnapInfo,0,sizeof(SnapInfo));

	SnapInfo.hWnd = hwnd;
	SnapInfo.wParam = wParam;
	SnapInfo.lParam = lParam;
	if (CallService("Utils/SnapWindowProc",(WPARAM)&SnapInfo,msg)!=0){return(TRUE);};
	};
	};
	*/
	switch(msg) {
  case WM_ACTIVATE:
	  {
		  if(g_bTransparentFlag)
		  {
			  BYTE alpha;
			  if ((wParam!=WA_INACTIVE || ((HWND)lParam==hwnd) || GetParent((HWND)lParam)==hwnd))
			  {
				  HWND hw=lParam?GetParent((HWND)lParam):0;
				  alpha=db_get_b(NULL,"CList","Alpha",SETTING_ALPHA_DEFAULT);
				  if (hw) SetWindowPos(hw,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
				  CLUI_SmoothAlphaTransition(hwnd, alpha, 1);
			  }
		  }
	  }
	  return DefWindowProc(hwnd, msg, wParam, lParam);

  case WM_NOTIFY:
  case WM_PARENTNOTIFY:
  case WM_SYSCOMMAND:
	  return SendMessage(pcli->hwndContactList,msg,wParam,lParam);

  case WM_MOVE:
	  if (g_CluiData.fDocked) return 1;
	  break;

  case WM_WINDOWPOSCHANGING:
	  {
		  if (g_CluiData.mutexPreventDockMoving)
		  {
			  WINDOWPOS *wp;
			  wp=(WINDOWPOS*)lParam;
			  wp->flags|=SWP_NOMOVE/*|SWP_NOSIZE*/;
			  wp->flags&=(wp->flags&~SWP_NOACTIVATE);
			  return DefWindowProc(hwnd, msg, wParam, lParam);
		  }
		  break;
	  }
  case WM_WINDOWPOSCHANGED:
	  {
		  if (g_CluiData.fDocked && g_CluiData.mutexPreventDockMoving)
			  return 0;
	  }
	  break;
  case WM_NCPAINT:
  case WM_PAINT:
	  {
		  //ValidateRect(hwnd,NULL);
		  return DefWindowProc(hwnd, msg, wParam, lParam);
	  }
  case WM_ERASEBKGND:
	  {
		  return 1;
	  }
	};
	return DefWindowProc(hwnd, msg, wParam, lParam);
};

static HWND CreateSubContainerWindow(HWND parent,int x,int y,int width,int height)
{
	HWND hwnd;
	hwnd=CreateWindowEx(g_proc_SetLayeredWindowAttributesNew ? WS_EX_LAYERED:0,CLUIFrameSubContainerClassName,TEXT("SubContainerWindow"),WS_POPUP|(!g_CluiData.fLayered ? WS_BORDER : 0),x,y,width,height,parent,0,g_hInst,0);
	SetWindowLongPtr(hwnd,GWL_STYLE,GetWindowLongPtr(hwnd,GWL_STYLE)&~(WS_CAPTION|WS_BORDER));
	if (g_CluiData.fOnDesktop)
	{
		HWND hProgMan=FindWindow(TEXT("Progman"),NULL);
		if (IsWindow(hProgMan))
			SetParent(hwnd,hProgMan);
	}


	return hwnd;
};



static LRESULT CALLBACK CLUIFrameContainerWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

	RECT rect;
	int Frameid;

	Frameid=(GetWindowLongPtr(hwnd,GWLP_USERDATA));
	memset(&rect,0,sizeof(rect));
	/*
	if ((msg == WM_MOVE) || (msg == WM_MOVING) || (msg == WM_NCLBUTTONDOWN) || (msg == WM_SYSCOMMAND)  )
	{
	if (ServiceExists("Utils/SnapWindowProc"))
	{
	SnapWindowProc_t SnapInfo;
	memset(&SnapInfo,0,sizeof(SnapInfo));

	SnapInfo.hWnd = hwnd;
	SnapInfo.wParam = wParam;
	SnapInfo.lParam = lParam;
	if (CallService("Utils/SnapWindowProc",(WPARAM)&SnapInfo,msg)!=0){return(TRUE);};
	};
	};
	*/
	switch(msg)
	{

	case WM_CREATE:
		{
			int framepos;

			framepos=id2pos(Frameid);
			//SetWindowPos(Frames[framepos].TitleBar.hwndTip, HWND_TOPMOST,0, 0, 0, 0,SWP_NOMOVE | SWP_NOSIZE  );

			return(0);
		};
	case WM_GETMINMAXINFO:
		//DefWindowProc(hwnd,msg,wParam,lParam);
		{
			int framepos;
			MINMAXINFO minmax;


			framepos=id2pos(Frameid);
			if(framepos<0||framepos>=g_nFramesCount){break;};
			if (!g_pfwFrames[framepos].minmaxenabled){break;};
			if (g_pfwFrames[framepos].ContainerWnd==0){break;};

			if (g_pfwFrames[framepos].Locked)
			{
				RECT rct;

				GetWindowRect(hwnd,&rct);
				((LPMINMAXINFO)lParam)->ptMinTrackSize.x=rct.right-rct.left;
				((LPMINMAXINFO)lParam)->ptMinTrackSize.y=rct.bottom-rct.top;
				((LPMINMAXINFO)lParam)->ptMaxTrackSize.x=rct.right-rct.left;
				((LPMINMAXINFO)lParam)->ptMaxTrackSize.y=rct.bottom-rct.top;
				//
				//return(0);
			};


			memset(&minmax,0,sizeof(minmax));
			if (SendMessage(g_pfwFrames[framepos].hWnd,WM_GETMINMAXINFO,(WPARAM)0,(LPARAM)&minmax)==0)
			{
				RECT border;
				int tbh=g_nTitleBarHeight*btoint(g_pfwFrames[framepos].TitleBar.ShowTitleBar);
				GetBorderSize(hwnd,&border);
				if (minmax.ptMaxTrackSize.x!=0&&minmax.ptMaxTrackSize.y!=0){

					((LPMINMAXINFO)lParam)->ptMinTrackSize.x=minmax.ptMinTrackSize.x;
					((LPMINMAXINFO)lParam)->ptMinTrackSize.y=minmax.ptMinTrackSize.y;
					((LPMINMAXINFO)lParam)->ptMaxTrackSize.x=minmax.ptMaxTrackSize.x+border.left+border.right;
					((LPMINMAXINFO)lParam)->ptMaxTrackSize.y=minmax.ptMaxTrackSize.y+tbh+border.top+border.bottom;
				};

			}
			else
			{


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



		}
		//return 0;

	case WM_MOVE:
		{
			int framepos;
			RECT rect;

			framepos=id2pos(Frameid);

			if(framepos<0||framepos>=g_nFramesCount){break;};
			if (g_pfwFrames[framepos].ContainerWnd==0){return(0);};

			GetWindowRect(g_pfwFrames[framepos].ContainerWnd,&rect);
			g_pfwFrames[framepos].FloatingPos.x=rect.left;
			g_pfwFrames[framepos].FloatingPos.y=rect.top;
			g_pfwFrames[framepos].FloatingSize.x=rect.right-rect.left;
			g_pfwFrames[framepos].FloatingSize.y=rect.bottom-rect.top;

			CLUIFramesStoreFrameSettings(framepos);

			if ( g_pfwFrames[framepos].floating )
			{
				POINT curpt,ofspt, newpt, newpos;
				RECT rcwnd, rcOverlap, rcMiranda;

				GetCursorPos(&curpt);
				rcwnd.bottom=curpt.y+5;
				rcwnd.top=curpt.y;
				rcwnd.left=curpt.x;
				rcwnd.right=curpt.x+5;

				GetWindowRect(pcli->hwndContactList, &rcMiranda );
				//GetWindowRect( Frames[pos].ContainerWnd, &rcwnd );
				//IntersectRect( &rcOverlap, &rcwnd, &rcMiranda )


				if (IntersectRect( &rcOverlap, &rcwnd, &rcMiranda ))
				{
					GetCursorPos(&curpt);
					GetWindowRect( g_pfwFrames[framepos].hWnd, &rcwnd );
					rcwnd.left=rcwnd.right-rcwnd.left;
					rcwnd.top=rcwnd.bottom-rcwnd.top;
					newpos.x=curpt.x;newpos.y=curpt.y;
					if (curpt.x>=(rcMiranda.right-1)){newpos.x=curpt.x+5;};
					if (curpt.x<=(rcMiranda.left+1)){newpos.x=curpt.x-(rcwnd.left)-5;};
					if (curpt.y>=(rcMiranda.bottom-1)){newpos.y=curpt.y+5;};
					if (curpt.y<=(rcMiranda.top+1)){newpos.y=curpt.y-(rcwnd.top)-5;};
					ofspt.x=0;ofspt.y=0;
					//ClientToScreen(Frames[pos].TitleBar.hwnd,&ofspt);
					GetWindowRect(g_pfwFrames[framepos].TitleBar.hwnd,&rcwnd);
					ofspt.x=curpt.x-ofspt.x;ofspt.y=curpt.y-ofspt.y;

					g_pfwFrames[framepos].FloatingPos.x=newpos.x;
					g_pfwFrames[framepos].FloatingPos.y=newpos.y;
					CLUIFrames_SetFrameFloat(Frameid,0);
					//SetWindowPos(Frames[pos].ContainerWnd,0,newpos.x,newpos.y,0,0,SWP_NOSIZE);


					newpt.x=0;newpt.y=0;
					ClientToScreen(g_pfwFrames[framepos].TitleBar.hwnd,&newpt);

					GetWindowRect( g_pfwFrames[framepos].hWnd, &rcwnd );
					SetCursorPos(newpt.x+(rcwnd.right-rcwnd.left)/2,newpt.y+(rcwnd.bottom-rcwnd.top)/2);
					GetCursorPos(&curpt);

					g_pfwFrames[framepos].TitleBar.oldpos=curpt;


					return(0);
				};

			};


			return(0);
		};

	case WM_SIZE:
		{
			int framepos;
			RECT rect;

			CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);

			framepos=id2pos(Frameid);

			if(framepos<0||framepos>=g_nFramesCount){break;};
			if (g_pfwFrames[framepos].ContainerWnd==0){return(0);};
			CLUIFrameResizeFloatingFrame(framepos);

			GetWindowRect(g_pfwFrames[framepos].ContainerWnd,&rect);
			g_pfwFrames[framepos].FloatingPos.x=rect.left;
			g_pfwFrames[framepos].FloatingPos.y=rect.top;
			g_pfwFrames[framepos].FloatingSize.x=rect.right-rect.left;
			g_pfwFrames[framepos].FloatingSize.y=rect.bottom-rect.top;

			CLUIFramesStoreFrameSettings(framepos);


			return(0);
		};
	case WM_LBUTTONDOWN:
		{
			if (db_get_b(NULL,"CLUI","ClientAreaDrag",SETTING_CLIENTDRAG_DEFAULT)) {
				POINT pt;
				GetCursorPos(&pt);
				return SendMessage( hwnd, WM_SYSCOMMAND, SC_MOVE|HTCAPTION,MAKELPARAM(pt.x,pt.y));
			}
			break;
		}
	case WM_CLOSE:
		{
			DestroyWindow(hwnd);
			break;
		};

	case WM_DESTROY:
		{
			//{ CLUIFramesStoreAllFrames();};
			return(0);
		};
		/*
		case WM_COMMAND:
		case WM_NOTIFY:
		return(SendMessage(pcli->hwndContactList,msg,wParam,lParam));
		*/


	};
	return DefWindowProc(hwnd, msg, wParam, lParam);
};
static HWND CreateContainerWindow(HWND parent,int x,int y,int width,int height)
{
	return(CreateWindow(TEXT("FramesContainer"),TEXT("FramesContainer"),WS_POPUP|WS_THICKFRAME,x,y,width,height,parent,0,g_hInst,0));
};


static int _us_DoSetFrameFloat(WPARAM wParam,LPARAM lParam)
{
	HWND hwndtmp,hwndtooltiptmp;


	int pos = id2pos( wParam );
	if ( pos >= 0&& pos < g_nFramesCount )

		if (g_pfwFrames[pos].floating || (lParam&2))
		{
			if (g_pfwFrames[pos].OwnerWindow!=(HWND)-2 &&g_pfwFrames[pos].visible)
			{
				if (g_pfwFrames[pos].OwnerWindow==0) g_pfwFrames[pos].OwnerWindow=CreateSubContainerWindow(pcli->hwndContactList,g_pfwFrames[pos].FloatingPos.x,g_pfwFrames[pos].FloatingPos.y,10,10);
				CLUI_ShowWindowMod(g_pfwFrames[pos].OwnerWindow,(g_pfwFrames[pos].visible && g_pfwFrames[pos].collapsed && IsWindowVisible(pcli->hwndContactList))?SW_SHOW/*NOACTIVATE*/:SW_HIDE);
				SetParent(g_pfwFrames[pos].hWnd,g_pfwFrames[pos].OwnerWindow);
				SetParent(g_pfwFrames[pos].TitleBar.hwnd,pcli->hwndContactList);
				SetWindowLongPtr(g_pfwFrames[pos].OwnerWindow,GWLP_USERDATA,g_pfwFrames[pos].id);
				g_pfwFrames[pos].floating=FALSE;
				if (!(lParam&2))
				{
					DestroyWindow(g_pfwFrames[pos].ContainerWnd);
					g_pfwFrames[pos].ContainerWnd=0;
				}
			}
			else
			{
				SetParent(g_pfwFrames[pos].hWnd,pcli->hwndContactList);
				SetParent(g_pfwFrames[pos].TitleBar.hwnd,pcli->hwndContactList);
				g_pfwFrames[pos].floating=FALSE;
				if (g_pfwFrames[pos].ContainerWnd) DestroyWindow(g_pfwFrames[pos].ContainerWnd);
				g_pfwFrames[pos].ContainerWnd=0;
			}
		}
		else
		{
			RECT recttb,rectw,border;
			int temp;
			int neww,newh;
			BOOLEAN locked;

			g_pfwFrames[pos].oldstyles=GetWindowLongPtr(g_pfwFrames[pos].hWnd,GWL_STYLE);
			g_pfwFrames[pos].TitleBar.oldstyles=GetWindowLongPtr(g_pfwFrames[pos].TitleBar.hwnd,GWL_STYLE);
			locked=g_pfwFrames[pos].Locked;
			g_pfwFrames[pos].Locked=FALSE;
			g_pfwFrames[pos].minmaxenabled=FALSE;

			GetWindowRect(g_pfwFrames[pos].hWnd,&rectw);
			GetWindowRect(g_pfwFrames[pos].TitleBar.hwnd,&recttb);
			if (!g_pfwFrames[pos].TitleBar.ShowTitleBar){
				recttb.top=recttb.bottom=recttb.left=recttb.right=0;
			};

			g_pfwFrames[pos].ContainerWnd=CreateContainerWindow(pcli->hwndContactList,g_pfwFrames[pos].FloatingPos.x,g_pfwFrames[pos].FloatingPos.y,10,10);




			SetParent(g_pfwFrames[pos].hWnd,g_pfwFrames[pos].ContainerWnd);
			SetParent(g_pfwFrames[pos].TitleBar.hwnd,g_pfwFrames[pos].ContainerWnd);
			if (g_pfwFrames[pos].OwnerWindow!=(HWND)-2 && g_pfwFrames[pos].OwnerWindow!=0)
			{
				DestroyWindow(g_pfwFrames[pos].OwnerWindow);
				g_pfwFrames[pos].OwnerWindow=0;
			}

			GetBorderSize(g_pfwFrames[pos].ContainerWnd,&border);


			SetWindowLongPtr(g_pfwFrames[pos].ContainerWnd,GWLP_USERDATA,g_pfwFrames[pos].id);
			if ((lParam==1))
			{
				//if ((Frames[pos].FloatingPos.x!=0)&&(Frames[pos].FloatingPos.y!=0))
				{
					if (g_pfwFrames[pos].FloatingPos.x<0){g_pfwFrames[pos].FloatingPos.x=0;};
					if (g_pfwFrames[pos].FloatingPos.y<0){g_pfwFrames[pos].FloatingPos.y=0;};

					SetWindowPos(g_pfwFrames[pos].ContainerWnd,HWND_TOPMOST,g_pfwFrames[pos].FloatingPos.x,g_pfwFrames[pos].FloatingPos.y,g_pfwFrames[pos].FloatingSize.x,g_pfwFrames[pos].FloatingSize.y,SWP_HIDEWINDOW|SWP_NOACTIVATE);
				}
			}
			else if (lParam==0)
			{
				neww=rectw.right-rectw.left+border.left+border.right;
				newh=(rectw.bottom-rectw.top)+(recttb.bottom-recttb.top)+border.top+border.bottom;
				if (neww<20){neww=40;};
				if (newh<20){newh=40;};
				if (g_pfwFrames[pos].FloatingPos.x<20){g_pfwFrames[pos].FloatingPos.x=40;};
				if (g_pfwFrames[pos].FloatingPos.y<20){g_pfwFrames[pos].FloatingPos.y=40;};

				SetWindowPos(g_pfwFrames[pos].ContainerWnd,HWND_TOPMOST,g_pfwFrames[pos].FloatingPos.x,g_pfwFrames[pos].FloatingPos.y,neww,newh,SWP_HIDEWINDOW|SWP_NOACTIVATE);
			};


			SetWindowText(g_pfwFrames[pos].ContainerWnd,g_pfwFrames[pos].TitleBar.tbname);

			temp=GetWindowLongPtr(g_pfwFrames[pos].ContainerWnd,GWL_EXSTYLE);
			temp|=WS_EX_TOOLWINDOW|WS_EX_TOPMOST ;
			SetWindowLongPtr(g_pfwFrames[pos].ContainerWnd,GWL_EXSTYLE,temp);

			g_pfwFrames[pos].floating=TRUE;
			g_pfwFrames[pos].Locked=locked;

		}
		CLUIFramesStoreFrameSettings(pos);
		g_pfwFrames[pos].minmaxenabled=TRUE;
		hwndtooltiptmp=g_pfwFrames[pos].TitleBar.hwndTip;

		hwndtmp=g_pfwFrames[pos].ContainerWnd;

		CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
		if (hwndtmp) SendMessage(hwndtmp,WM_SIZE,0,0);


		SetWindowPos(hwndtooltiptmp, HWND_TOPMOST,0, 0, 0, 0,SWP_NOMOVE | SWP_NOSIZE|SWP_NOACTIVATE  );

		return 0;
}


int CLUIFrameOnModulesLoad(WPARAM wParam,LPARAM lParam)
{
	/* HOOK */
	CLUIFramesLoadMainMenu();
	CLUIFramesCreateMenuForFrame(-1,-1,000010000,Menu_AddContextFrameMenuItem);
	return 0;
}
int CLUIFrameOnModulesUnload(WPARAM wParam,LPARAM lParam)
{
	//
	//if (MirandaExiting()) return 0;
	if (!_hmiVisible) return 0;
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiVisible, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiTBVisible, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiLock, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiColl, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiFloating, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiAlignTop, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiAlignClient, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiAlignBottom, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiBorder, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiAlignRoot, 1 );


	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiPosUp, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiPosDown, 1 );
	CallService( MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, ( LPARAM )_hmiPosRoot, 1 );


	CallService( MO_REMOVEMENUITEM, ( LPARAM )_hmiVisible, 1 );
	CallService( MO_REMOVEMENUITEM, ( LPARAM )_hmiTBVisible, 1 );
	CallService( MO_REMOVEMENUITEM, ( LPARAM )_hmiLock, 1 );
	CallService( MO_REMOVEMENUITEM, ( LPARAM )_hmiColl, 1 );
	CallService( MO_REMOVEMENUITEM, ( LPARAM )_hmiFloating, 1 );
	CallService( MO_REMOVEMENUITEM, ( LPARAM )_hmiBorder, 1 );
	CallService( MO_REMOVEMENUITEM, ( LPARAM )_hmiAlignRoot, 1 );
	CallService( MO_REMOVEMENUITEM, ( LPARAM )_hmiPosRoot, 1 );

	_hmiVisible=0;
	return 0;
}

int LoadCLUIFramesModule(void)
{
	WNDCLASS wndclass;
	WNDCLASS cntclass;
	WNDCLASS subconclass;
	InitializeCriticalSection(&_cluiFramesModuleCS);
	_cluiFramesModuleCSInitialized=TRUE;

	wndclass.style         = CS_DBLCLKS;//|CS_HREDRAW|CS_VREDRAW ;
	wndclass.lpfnWndProc   = CLUIFrameTitleBarProc;
	wndclass.cbClsExtra    = 0;
	wndclass.cbWndExtra    = 0;
	wndclass.hInstance     = g_hInst;
	wndclass.hIcon         = NULL;
	wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
	wndclass.lpszMenuName  = NULL;
	wndclass.lpszClassName = CLUIFrameTitleBarClassName;
	RegisterClass(&wndclass);

	subconclass.style         = CS_DBLCLKS;//|CS_HREDRAW|CS_VREDRAW ;
	subconclass.lpfnWndProc   = CLUIFrameSubContainerProc;
	subconclass.cbClsExtra    = 0;
	subconclass.cbWndExtra    = 0;
	subconclass.hInstance     = g_hInst;
	subconclass.hIcon         = NULL;
	subconclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	subconclass.hbrBackground = NULL;
	subconclass.lpszMenuName  = NULL;
	subconclass.lpszClassName = CLUIFrameSubContainerClassName;
	RegisterClass(&subconclass);

	//container helper

	cntclass.style         = CS_DBLCLKS/*|CS_HREDRAW|CS_VREDRAW*/|( IsWinVerXPPlus()  ? CS_DROPSHADOW : 0);
	cntclass.lpfnWndProc   = CLUIFrameContainerWndProc;
	cntclass.cbClsExtra    = 0;
	cntclass.cbWndExtra    = 0;
	cntclass.hInstance     = g_hInst;
	cntclass.hIcon         = NULL;
	cntclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	cntclass.hbrBackground = NULL;
	cntclass.lpszMenuName  = NULL;
	cntclass.lpszClassName = TEXT("FramesContainer");
	RegisterClass(&cntclass);
	//end container helper

	GapBetweenFrames=db_get_dw(NULL,"CLUIFrames","GapBetweenFrames",SETTING_GAPFRAMES_DEFAULT);

	g_nFramesCount=0;

	InitFramesMenus();

	ModernHookEvent(ME_SYSTEM_MODULESLOADED,CLUIFrameOnModulesLoad);
	ModernHookEvent(ME_CLIST_PREBUILDFRAMEMENU,CLUIFramesModifyContextMenuForFrame);
	ModernHookEvent(ME_CLIST_PREBUILDMAINMENU,CLUIFrameOnMainMenuBuild);
	ModernHookEvent(ME_SYSTEM_PRESHUTDOWN,  CLUIFrameOnModulesUnload);

    CreateCluiFramesServices();


	hWndExplorerToolBar	=FindWindowEx(0,0,TEXT("Shell_TrayWnd"),NULL);
	OnFrameTitleBarBackgroundChange(0,0);
	_fCluiFramesModuleNotStarted=FALSE;
	return 0;
}

static INT_PTR UnloadMainMenu()
{
	CLUIFrameOnModulesUnload(0,0);
	if(_hmiRoot!=(HANDLE)-1)
	{
		CallService(MS_CLIST_REMOVEMAINMENUITEM,(WPARAM)_hmiRoot,0);
		_hmiRoot=(HGENMENU)-1;
	}

	return (INT_PTR) _hmiRoot;
}

int UnLoadCLUIFramesModule(void)
{
	int i;

	_fCluiFramesModuleNotStarted=TRUE;
	if(hBmpBackground) {DeleteObject(hBmpBackground); hBmpBackground=NULL;}
	CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,0);
	CLUIFramesStoreAllFrames();


	UnitFramesMenu();
	UnloadMainMenu();
	for (i=0;i<g_nFramesCount;i++)
	{
		if (g_pfwFrames[i].hWnd!=pcli->hwndContactTree)
			DestroyWindow(g_pfwFrames[i].hWnd);

		g_pfwFrames[i].hWnd=(HWND)-1;
		DestroyWindow(g_pfwFrames[i].TitleBar.hwnd);
		g_pfwFrames[i].TitleBar.hwnd=(HWND)-1;
		if (g_pfwFrames[i].ContainerWnd && g_pfwFrames[i].ContainerWnd!=(HWND)(-2)&& g_pfwFrames[i].ContainerWnd!=(HWND)(-1)) DestroyWindow(g_pfwFrames[i].ContainerWnd);
		g_pfwFrames[i].ContainerWnd=(HWND)-1;
		if (g_pfwFrames[i].TitleBar.hmenu) DestroyMenu(g_pfwFrames[i].TitleBar.hmenu);
		if (g_pfwFrames[i].OwnerWindow && g_pfwFrames[i].OwnerWindow!=(HWND)(-2)&& g_pfwFrames[i].OwnerWindow!=(HWND)(-1))
			DestroyWindow(g_pfwFrames[i].OwnerWindow );
		g_pfwFrames[i].OwnerWindow=(HWND)-2;
        if (g_pfwFrames[i].UpdateRgn) DeleteObject(g_pfwFrames[i].UpdateRgn);

		if (g_pfwFrames[i].Name!=NULL) mir_free_and_nill(g_pfwFrames[i].Name);
		if (g_pfwFrames[i].szName!=NULL) mir_free_and_nill(g_pfwFrames[i].szName);
		if (g_pfwFrames[i].TitleBar.tbname!=NULL) mir_free_and_nill(g_pfwFrames[i].TitleBar.tbname);
		if (g_pfwFrames[i].TitleBar.sztbname!=NULL) mir_free_and_nill(g_pfwFrames[i].TitleBar.sztbname);
		if (g_pfwFrames[i].TitleBar.tooltip!=NULL) mir_free_and_nill(g_pfwFrames[i].TitleBar.tooltip);
		if (g_pfwFrames[i].TitleBar.sztooltip!=NULL) mir_free_and_nill(g_pfwFrames[i].TitleBar.sztooltip);

	}
	if(g_pfwFrames) free(g_pfwFrames);
	g_pfwFrames=NULL;
	g_nFramesCount=0;
	UnregisterClass(CLUIFrameTitleBarClassName,g_hInst);
	DeleteObject(_hTitleBarFont);

	_cluiFramesModuleCSInitialized=FALSE;
	DeleteCriticalSection(&_cluiFramesModuleCS);
	return 0;
}

static int _us_DoSetFramePaintProc(WPARAM wParam, LPARAM lParam)
{
	if (!wParam) return 0;
	{
		// LOOK REQUIRED OR SYNC CALL NEEDED
		FRAMEWND *frm=FindFrameByItsHWND((HWND)wParam);
		if (!frm) return 0;
		if (lParam)
			frm->PaintCallbackProc=(tPaintCallbackProc)lParam;
		else
			frm->PaintCallbackProc=NULL;
		return 1;
	}
}
int CLUIFrames_SetLayeredMode( BOOL fLayeredMode, HWND hwnd )
{
	int i;
	for(i=0;i<g_nFramesCount;i++)
	{
		if (fLayeredMode)
		{
			if (g_pfwFrames[i].visible && GetParent(g_pfwFrames[i].hWnd)==pcli->hwndContactList && g_pfwFrames[i].PaintCallbackProc==NULL)
			{
				//create owner window
				g_pfwFrames[i].OwnerWindow=CreateSubContainerWindow(pcli->hwndContactList,g_pfwFrames[i].FloatingPos.x,g_pfwFrames[i].FloatingPos.y,10,10);
				SetParent(g_pfwFrames[i].hWnd,g_pfwFrames[i].OwnerWindow);
			}
		}
		else
		{
			if (GetParent(g_pfwFrames[i].hWnd)==g_pfwFrames[i].OwnerWindow)
			{
				SetParent(g_pfwFrames[i].hWnd,hwnd);
				if ((INT_PTR)g_pfwFrames[i].OwnerWindow>0)
				{
					DestroyWindow(g_pfwFrames[i].OwnerWindow);
					g_pfwFrames[i].OwnerWindow=(HWND)-2;
				}
			}
		}
	}

	CLUIFrames_UpdateFrame((WPARAM)-1,0);  //update all frames
	return 0;
}

int CLUIFrames_UpdateBorders()
{
	for ( int i = 0; i < g_nFramesCount; i++ )
	{
		if ( !g_pfwFrames[i].floating )
		{
			DWORD style = (int)GetWindowLongPtr( g_pfwFrames[i].hWnd, GWL_STYLE ) & ( ~WS_BORDER );
			if ( !g_CluiData.fLayered && g_pfwFrames[i].UseBorder ) style|=WS_BORDER;
			SetWindowLongPtr( g_pfwFrames[i].hWnd, GWL_STYLE, style );
			CLUIFramesModifyMainMenuItems( g_pfwFrames[i].id, 0 );
			RedrawWindow( g_pfwFrames[i].hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE );
		};
	}

	return 0;
}