BOOL ImageArray_DrawImage(LP_IMAGE_ARRAY_DATA iad, int pos, HDC hdcDest, int nXDest, int nYDest)
{
	if (hdcDest == NULL || pos < 0 || pos >= iad->nodes_size)
		return FALSE;

	EnterCriticalSection(&iad->cs);

	{
		int w, h, i;

		if (iad->width_based)
		{
			w = 0;
			h = 0;
			for(i = 0; i < pos; i++)
			{
				h += iad->nodes[i].height;
			}
		}
		else
		{
			h = 0;
			w = 0;
			for(i = 0; i < pos; i++)
			{
				w += iad->nodes[i].width;
			}
		}
    if (!gdiPlusFail) //Use gdi+ engine
    {
		DrawAvatarImageWithGDIp(hdcDest, nXDest, nYDest, iad->nodes[pos].width, iad->nodes[pos].height, iad->img, w, h, iad->nodes[pos].width, iad->nodes[pos].height,0);
    }
    else
    {
      BLENDFUNCTION bf={AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
      AlphaBlend(hdcDest, nXDest, nYDest, iad->nodes[pos].width, iad->nodes[pos].height, iad->hdc, w, h, iad->nodes[pos].width, iad->nodes[pos].height,bf);
    }
//		BitBlt(hdcDest, nXDest, nYDest, iad->nodes[pos].width, iad->nodes[pos].height, iad->hdc, w, h, SRCCOPY);
	}

	return FALSE;
}
Beispiel #2
0
static BOOL CALLBACK DlgSkinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_DESTROY: 
		{
			if (hPreviewBitmap) DeleteObject(hPreviewBitmap);
			break;
		}

	case WM_INITDIALOG:
		{ 
			int it;
			TranslateDialogDefault(hwndDlg);
			it=FillAvailableSkinList(hwndDlg);
			{
				/* Text Colors */
				DWORD c1,c2,c3,c4;
				c1=DBGetContactSettingDword(NULL,"Menu", "TextColour", CLCDEFAULT_TEXTCOLOUR);
				c2=DBGetContactSettingDword(NULL,"Menu", "SelTextColour", CLCDEFAULT_SELTEXTCOLOUR);
				c3=DBGetContactSettingDword(NULL,"FrameTitleBar", "TextColour", CLCDEFAULT_TEXTCOLOUR);
				c4=DBGetContactSettingDword(NULL,"StatusBar", "TextColour", CLCDEFAULT_TEXTCOLOUR);
				SendDlgItemMessage(hwndDlg,IDC_COLOUR_MENUNORMAL,CPM_SETCOLOUR,0,c1);                  
				SendDlgItemMessage(hwndDlg,IDC_COLOUR_MENUSELECTED,CPM_SETCOLOUR,0,c2);
				SendDlgItemMessage(hwndDlg,IDC_COLOUR_FRAMES,CPM_SETCOLOUR,0,c3);
				SendDlgItemMessage(hwndDlg,IDC_COLOUR_STATUSBAR,CPM_SETCOLOUR,0,c4);

				SendDlgItemMessage(hwndDlg,IDC_COLOUR_MENUNORMAL,CPM_SETDEFAULTCOLOUR,0,c1);                  
				SendDlgItemMessage(hwndDlg,IDC_COLOUR_MENUSELECTED,CPM_SETDEFAULTCOLOUR,0,c2);
				SendDlgItemMessage(hwndDlg,IDC_COLOUR_FRAMES,CPM_SETDEFAULTCOLOUR,0,c3);
				SendDlgItemMessage(hwndDlg,IDC_COLOUR_STATUSBAR,CPM_SETDEFAULTCOLOUR,0,c4);                              
				/* End of Text colors */
			}

			TreeView_SelectItem(GetDlgItem(hwndDlg,IDC_TREE1),(HTREEITEM)it);						
		}
		return 0;
	case WM_COMMAND:
		{
			int isLoad=0;
			switch (LOWORD(wParam)) 
			{
			case IDC_COLOUR_MENUNORMAL:
			case IDC_COLOUR_MENUSELECTED:
			case IDC_COLOUR_FRAMES:
			case IDC_COLOUR_STATUSBAR:
				SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
				break;

			case IDC_BUTTON_INFO:
				{
					char Author[255];
					char URL[MAX_PATH];
					char Contact[255];
					char Description[400];
					char text[2000];
					SkinListData *sd=NULL;  
					HTREEITEM hti=TreeView_GetSelection(GetDlgItem(hwndDlg,IDC_TREE1));				
					if (hti==0) return 0;
					{
						TVITEMA tvi={0};
						tvi.hItem=hti;
						tvi.mask=TVIF_HANDLE|TVIF_PARAM;
						TreeView_GetItem(GetDlgItem(hwndDlg,IDC_TREE1),&tvi);
						sd=(SkinListData*)(tvi.lParam);
					}
					if (!sd) return 0;
					if (sd->File && !strchr(sd->File,'%'))
					{
						GetPrivateProfileStringA("Skin_Description_Section","Author","(unknown)",Author,sizeof(Author),sd->File);
						GetPrivateProfileStringA("Skin_Description_Section","URL","",URL,sizeof(URL),sd->File);
						GetPrivateProfileStringA("Skin_Description_Section","Contact","",Contact,sizeof(Contact),sd->File);
						GetPrivateProfileStringA("Skin_Description_Section","Description","",Description,sizeof(Description),sd->File);
						_snprintf(text,sizeof(text),Translate("%s\n\n%s\n\nAuthor(s):\t %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s"),
							sd->Name,Description,Author,Contact,URL,sd->File);
					}
					else
					{
						_snprintf(text,sizeof(text),Translate("%s\n\n%s\n\nAuthor(s): %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s"),
							"Luna v0.4",Translate("This is default Modern Contact list skin based on 'Luna' theme"),"Angeli-Ka (graphics), FYR (template)","JID: [email protected]","modern.saopp.info",Translate("Inside library"));
					}
					MessageBoxA(hwndDlg,text,"Skin Information",MB_OK|MB_ICONINFORMATION);
				}
				break;
			case IDC_BUTTON_APPLY_SKIN:
				if (HIWORD(wParam)==BN_CLICKED)
				{ 		
					SkinListData *sd=NULL;  
					HTREEITEM hti=TreeView_GetSelection(GetDlgItem(hwndDlg,IDC_TREE1));				
					if (hti==0) return 0;
					{
						TVITEM tvi={0};
						tvi.hItem=hti;
						tvi.mask=TVIF_HANDLE|TVIF_PARAM;
						TreeView_GetItem(GetDlgItem(hwndDlg,IDC_TREE1),&tvi);
						sd=(SkinListData*)(tvi.lParam);
					}
					if (!sd) return 0;
					if (glSkinWasModified>0)
					{
						int res=0;
						if (glSkinWasModified==1)
							res=MessageBoxA(hwndDlg,Translate("Skin editor contains not stored changes.\n\nAll changes will be lost.\n\n Continue to load new skin?"),Translate("Warning!"),MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2|MB_TOPMOST);
						else
							res=MessageBoxA(hwndDlg,Translate("Current skin was not saved to file.\n\nAll changes will be lost.\n\n Continue to load new skin?"),Translate("Warning!"),MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2|MB_TOPMOST);
						if (res!=IDOK) return 0;
					}
					LoadSkinFromIniFile(sd->File);
					LoadSkinFromDB();	
					glOtherSkinWasLoaded=TRUE;
					pcli->pfnClcBroadcast( INTM_RELOADOPTIONS,0,0);
					CLUIFramesOnClistResize2(0,0,0);
					RedrawCompleteWindow();        
					CLUIFramesOnClistResize2(0,0,0);
					{
						HWND hwnd=(HWND)CallService(MS_CLUI_GETHWND,0,0);
						RECT rc={0};
						GetWindowRect(hwnd, &rc);
						OnMoving(hwnd,&rc);
					}
					if (hCLUIwnd)
					{
						SendDlgItemMessage(hCLUIwnd,IDC_LEFTMARGINSPIN,UDM_SETPOS,0,DBGetContactSettingByte(NULL,"CLUI","LeftClientMargin",0));
						SendDlgItemMessage(hCLUIwnd,IDC_RIGHTMARGINSPIN,UDM_SETPOS,0,DBGetContactSettingByte(NULL,"CLUI","RightClientMargin",0));
						SendDlgItemMessage(hCLUIwnd,IDC_TOPMARGINSPIN,UDM_SETPOS,0,DBGetContactSettingByte(NULL,"CLUI","TopClientMargin",0));
						SendDlgItemMessage(hCLUIwnd,IDC_BOTTOMMARGINSPIN,UDM_SETPOS,0,DBGetContactSettingByte(NULL,"CLUI","BottomClientMargin",0));
					}
				}
				break;
			case IDC_BUTTON_LOAD:
				isLoad=1;
				if (HIWORD(wParam)==BN_CLICKED)
				{
					{   		
						char str[MAX_PATH]={0};
						OPENFILENAMEA ofn={0};
						char filter[512]={0};
						int res=0;
						ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
						ofn.hwndOwner = hwndDlg;
						ofn.hInstance = NULL;

						sprintf(filter,"%s",Translate("Miranda skin file"));
						memmove(filter+mir_strlen(filter)," (*.msf)\0*.MSF\0\0",sizeof(" (*.msf)\0*.MSF\0\0"));
						ofn.lpstrFilter = filter;
						ofn.lpstrFile = str;
						ofn.Flags = isLoad?(OFN_FILEMUSTEXIST | OFN_HIDEREADONLY) : (OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY);
						ofn.nMaxFile = sizeof(str);
						ofn.nMaxFileTitle = MAX_PATH;
						ofn.lpstrDefExt = "msf";

						{
							DWORD tick=GetTickCount();
							res=GetOpenFileNameA(&ofn);
							if(!res) 
								if (GetTickCount()-tick<100)
								{
									res=GetOpenFileNameA(&ofn);
									if(!res) break;
								}
								else break;
						}
						if (res)
						{
							int it=AddSkinToListFullName(hwndDlg,ofn.lpstrFile);
							TreeView_SelectItem(GetDlgItem(hwndDlg,IDC_TREE1),(HTREEITEM)it);
							//SendDlgItemMessage(hwndDlg,IDC_SKINS_LIST,LB_SETCURSEL,it,0); 
							//SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_SKINS_LIST,LBN_SELCHANGE),0);
						}
					}
				}
			}
			break;
		}
	case WM_DRAWITEM:
		if (wParam==IDC_PREVIEW)
		{
			//TODO:Draw hPreviewBitmap here
			HDC memDC, imgDC;
			HBITMAP hbmp,holdbmp,imgOldbmp;
			int mWidth, mHeight;
			RECT workRect={0};
			HBRUSH hbr=CreateSolidBrush(GetSysColor(COLOR_3DFACE));
			DRAWITEMSTRUCT *dis=(DRAWITEMSTRUCT *)lParam;
			mWidth=dis->rcItem.right-dis->rcItem.left;
			mHeight=dis->rcItem.bottom-dis->rcItem.top;
			memDC=CreateCompatibleDC(dis->hDC);
			hbmp=CreateBitmap32(mWidth,mHeight);
			holdbmp=SelectObject(memDC,hbmp);
			workRect=dis->rcItem;
			OffsetRect(&workRect,-workRect.left,-workRect.top);
			FillRect(memDC,&workRect,hbr);     
			DeleteObject(hbr);
			if (hPreviewBitmap)
			{
				//variables
				BITMAP bmp={0};
				POINT imgPos={0};
				int wWidth,wHeight;
				int dWidth,dHeight;
				float xScale=1, yScale=1;
				//GetSize
				GetObject(hPreviewBitmap,sizeof(BITMAP),&bmp);
				wWidth=workRect.right-workRect.left;
				wHeight=workRect.bottom-workRect.top;
				if (wWidth<bmp.bmWidth) xScale=(float)wWidth/bmp.bmWidth;
				if (wHeight<bmp.bmHeight) yScale=(float)wHeight/bmp.bmHeight;
				xScale=min(xScale,yScale);
				yScale=xScale;                    
				dWidth=(int)(xScale*bmp.bmWidth);
				dHeight=(int)(yScale*bmp.bmHeight);
				//CalcPosition
				imgPos.x=workRect.left+((wWidth-dWidth)>>1);
				imgPos.y=workRect.top+((wHeight-dHeight)>>1);     
				//DrawImage
				if (!gl_b_GDIPlusFail) //Use gdi+ engine
				{
					DrawAvatarImageWithGDIp(memDC,imgPos.x,imgPos.y,dWidth,dHeight,hPreviewBitmap,0,0,bmp.bmWidth,bmp.bmHeight,8,255);
				}   
				else
				{
					BLENDFUNCTION bf={AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
					imgDC=CreateCompatibleDC(dis->hDC);
					imgOldbmp=SelectObject(imgDC,hPreviewBitmap);                 
					mod_AlphaBlend(memDC,imgPos.x,imgPos.y,dWidth,dHeight,imgDC,0,0,bmp.bmWidth,bmp.bmHeight,bf);
					SelectObject(imgDC,imgOldbmp);
					mod_DeleteDC(imgDC);
				}
			}
			BitBlt(dis->hDC,dis->rcItem.left,dis->rcItem.top,mWidth,mHeight,memDC,0,0,SRCCOPY);
			SelectObject(memDC,holdbmp);
			DeleteObject(hbmp);
			mod_DeleteDC(memDC);
		}
		break;

	case WM_NOTIFY:
		switch (((LPNMHDR)lParam)->idFrom) 
		{
		case IDC_TREE1:
			{		
				NMTREEVIEWA * nmtv = (NMTREEVIEWA *) lParam;
				if (!nmtv) return 0;
				if (nmtv->hdr.code==TVN_SELCHANGEDA
					|| nmtv->hdr.code==TVN_SELCHANGEDW)
				{	
					SkinListData * sd=NULL;
					if (hPreviewBitmap) 
					{
						DeleteObject(hPreviewBitmap);
						hPreviewBitmap=NULL;
					}
					if (nmtv->itemNew.lParam)
					{
						//char sdFile[MAX_PATH]={0};
						sd=(SkinListData*)nmtv->itemNew.lParam;
						//PathCompactPathExA(sdFile,sd->File,60,0);
						{
							char buf[MAX_PATH];
							CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)sd->File, (LPARAM)buf);
							SendDlgItemMessageA(hwndDlg,IDC_EDIT_SKIN_FILENAME,WM_SETTEXT,0,(LPARAM)buf); //TODO made filepath unicode
						}
						{
							char prfn[MAX_PATH]={0};
							char imfn[MAX_PATH]={0};
							char skinfolder[MAX_PATH]={0};
							GetPrivateProfileStringA("Skin_Description_Section","Preview","",imfn,sizeof(imfn),sd->File);
							GetSkinFolder(sd->File,skinfolder);
							_snprintf(prfn,sizeof(prfn),"%s\\%s",skinfolder,imfn);
							CallService(MS_UTILS_PATHTOABSOLUTE,(WPARAM)prfn,(LPARAM) imfn);
							hPreviewBitmap=skin_LoadGlyphImage(imfn);
						}
						EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_APPLY_SKIN),TRUE);
						EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_INFO),TRUE);
						if (hPreviewBitmap) 
							InvalidateRect(GetDlgItem(hwndDlg,IDC_PREVIEW),NULL,TRUE);
						else  //prepeare text
						{
							char Author[255];
							char URL[MAX_PATH];
							char Contact[255];
							char Description[400];
							char text[2000];
							SkinListData* sd=NULL;
							HTREEITEM hti=TreeView_GetSelection(GetDlgItem(hwndDlg,IDC_TREE1));				
							if (hti==0) return 0;
							{
								TVITEM tvi={0};
								tvi.hItem=hti;
								tvi.mask=TVIF_HANDLE|TVIF_PARAM;
								TreeView_GetItem(GetDlgItem(hwndDlg,IDC_TREE1),&tvi);
								sd=(SkinListData*)(tvi.lParam);
							}
							if (!sd) return 0;

							if(sd->File && !strchr(sd->File,'%'))
							{
								GetPrivateProfileStringA("Skin_Description_Section","Author","(unknown)",Author,sizeof(Author),sd->File);
								GetPrivateProfileStringA("Skin_Description_Section","URL","",URL,sizeof(URL),sd->File);
								GetPrivateProfileStringA("Skin_Description_Section","Contact","",Contact,sizeof(Contact),sd->File);
								GetPrivateProfileStringA("Skin_Description_Section","Description","",Description,sizeof(Description),sd->File);
								_snprintf(text,sizeof(text),Translate("Preview is not available\n\n%s\n----------------------\n\n%s\n\nAUTHOR(S):\n%s\n\nCONTACT:\n%s\n\nHOMEPAGE:\n%s"),
									sd->Name,Description,Author,Contact,URL);
							}
							else
							{
								_snprintf(text,sizeof(text),Translate("%s\n\n%s\n\nAUTHORS:\n%s\n\nCONTACT:\n%s\n\nWEB:\n%s\n\n\n"),
									"Luna v0.4",
									Translate("This is default Modern Contact list skin based on 'Luna' theme"),
									"graphics by Angeli-Ka\ntemplate by FYR",
									"JID: [email protected]",
									"modern.saopp.info"
									);
							}
							ShowWindow(GetDlgItem(hwndDlg,IDC_PREVIEW),SW_HIDE);
							ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC_INFO),SW_SHOW);
							SendDlgItemMessageA(hwndDlg,IDC_STATIC_INFO,WM_SETTEXT,0,(LPARAM)text);
					}					
				}
				else
				{
					//no selected
					SendDlgItemMessage(hwndDlg,IDC_EDIT_SKIN_FILENAME,WM_SETTEXT,0,(LPARAM)TranslateT("Select skin from list"));
					EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_APPLY_SKIN),FALSE);
					EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_INFO),FALSE);
					SendDlgItemMessageA(hwndDlg,IDC_STATIC_INFO,WM_SETTEXT,0,(LPARAM)Translate("Please select skin to apply"));
					ShowWindow(GetDlgItem(hwndDlg,IDC_PREVIEW),SW_HIDE);
				}
				ShowWindow(GetDlgItem(hwndDlg,IDC_PREVIEW),hPreviewBitmap?SW_SHOW:SW_HIDE);
				return 0;
			}			
		else if (nmtv->hdr.code==TVN_SELCHANGEDA || nmtv->hdr.code==TVN_SELCHANGEDW)
		{
			if (nmtv->itemOld.lParam)
				mir_free((void*)(nmtv->itemOld.lParam));
			return 0;
		}
		break;
		}
	case 0:
		switch (((LPNMHDR)lParam)->code)
		{
		case PSN_APPLY:
			{
				{
					DWORD tick=GetTickCount();
					{
						/* Text Colors */
						DWORD c1,c2,c3,c4;
						c1=SendDlgItemMessage(hwndDlg,IDC_COLOUR_MENUNORMAL,CPM_GETCOLOUR,0,0);
						c2=SendDlgItemMessage(hwndDlg,IDC_COLOUR_MENUSELECTED,CPM_GETCOLOUR,0,0);
						c3=SendDlgItemMessage(hwndDlg,IDC_COLOUR_FRAMES,CPM_GETCOLOUR,0,0);
						c4=SendDlgItemMessage(hwndDlg,IDC_COLOUR_STATUSBAR,CPM_GETCOLOUR,0,0);
						DBWriteContactSettingDword(NULL,"Menu", "TextColour", c1);
						DBWriteContactSettingDword(NULL,"Menu", "SelTextColour", c2);
						DBWriteContactSettingDword(NULL,"FrameTitleBar", "TextColour", c3);
						DBWriteContactSettingDword(NULL,"StatusBar", "TextColour", c4);
						/* End of Text colors */
					}
					pcli->pfnClcBroadcast( INTM_RELOADOPTIONS,0,0);
					NotifyEventHooks(ME_BACKGROUNDCONFIG_CHANGED,0,0);
					pcli->pfnClcBroadcast( INTM_INVALIDATE,0,0);	
					RedrawWindow(GetParent(pcli->hwndContactTree),NULL,NULL,RDW_INVALIDATE|RDW_FRAME|RDW_ALLCHILDREN);
				}
				return 0;
			}
			break;
		}
		break;
	}
}
void Cache_ProceedAvatarInList(ClcData *dat, ClcContact *contact)
{
	avatarCacheEntry * ace = contact->avatar_data;
	int old_pos = contact->avatar_pos;

	if (ace == NULL || ace->dwFlags == AVS_BITMAP_EXPIRED || ace->hbmPic == NULL) {
		// Avatar was not ready or removed - need to remove it from cache
		if (old_pos >= 0) {
			ImageArray_RemoveImage(&dat->avatar_cache, old_pos);

			// Update all items
			ExecuteOnAllContacts(dat, ReduceAvatarPosition, (void *)&old_pos);
			contact->avatar_pos = AVATAR_POS_DONT_HAVE;
			return;
		}
	}
	else if (contact->avatar_data->hbmPic != NULL) //Lets Add it
	{
		// Clipping width and height
		LONG width_clip = dat->avatars_maxwidth_size ? dat->avatars_maxwidth_size : dat->avatars_maxheight_size;
		LONG height_clip = dat->avatars_maxheight_size;

		if (height_clip * ace->bmWidth / ace->bmHeight <= width_clip)
			width_clip = height_clip * ace->bmWidth / ace->bmHeight;
		else
			height_clip = width_clip * ace->bmHeight / ace->bmWidth;

		if (wildcmpit(contact->avatar_data->szFilename, _T("*.gif"))) {
			if (old_pos == AVATAR_POS_ANIMATED)
				AniAva_RemoveAvatar(contact->hContact);

			int res = AniAva_AddAvatar(contact->hContact, contact->avatar_data->szFilename, width_clip, height_clip);
			if (res) {
				contact->avatar_pos = AVATAR_POS_ANIMATED;
				contact->avatar_size.cy = HIWORD(res);
				contact->avatar_size.cx = LOWORD(res);
				return;
			}
		}

		// Create objs
		void * pt;
		HDC hdc = CreateCompatibleDC(dat->avatar_cache.hdc);
		HBITMAP hDrawBmp = ske_CreateDIB32Point(width_clip, height_clip, &pt);
		HBITMAP oldBmp = (HBITMAP)SelectObject(hdc, hDrawBmp);

		// need to draw avatar bitmap here
		DrawAvatarImageWithGDIp(hdc, 0, 0, width_clip, height_clip, ace->hbmPic, 0, 0, ace->bmWidth, ace->bmHeight, ace->dwFlags, 255);
		SelectObject(hdc, oldBmp);
		DeleteDC(hdc);

		// Add to list
		if (old_pos >= 0) {
			ImageArray_ChangeImage(&dat->avatar_cache, hDrawBmp, old_pos);
			contact->avatar_pos = old_pos;
		}
		else contact->avatar_pos = ImageArray_AddImage(&dat->avatar_cache, hDrawBmp, -1);

		if (old_pos == AVATAR_POS_ANIMATED && contact->avatar_pos != AVATAR_POS_ANIMATED)
			AniAva_RemoveAvatar(contact->hContact);

		DeleteObject(hDrawBmp);
	}
}
Beispiel #4
0
INT_PTR CALLBACK DlgSkinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_DESTROY:
		if (hPreviewBitmap)
			ske_UnloadGlyphImage(hPreviewBitmap);
		break;

	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		SetDlgItemText(hwndDlg, IDC_SKINFOLDERLABEL, SkinsFolder);
		{
			HTREEITEM it = FillAvailableSkinList(hwndDlg);
			HWND wnd = GetDlgItem(hwndDlg, IDC_TREE1);
			TreeView_SelectItem(wnd, it);
		}
		return 0;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDC_COLOUR_MENUNORMAL:
		case IDC_COLOUR_MENUSELECTED:
		case IDC_COLOUR_FRAMES:
		case IDC_COLOUR_STATUSBAR:
			SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
			break;

		case IDC_BUTTON_INFO:
		{
			TCHAR Author[255], URL[MAX_PATH], Contact[255], Description[400], text[2000];
			SkinListData *sd = NULL;
			HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1));
			if (hti == 0) return 0;
			{
				TVITEM tvi = { 0 };
				tvi.hItem = hti;
				tvi.mask = TVIF_HANDLE | TVIF_PARAM;
				TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi);
				sd = (SkinListData*)(tvi.lParam);
			}
			if (!sd) return 0;
			if (sd->File && !_tcschr(sd->File, _T('%'))) {
				GetPrivateProfileString(_T("Skin_Description_Section"), _T("Author"), TranslateT("( unknown )"), Author, _countof(Author), sd->File);
				GetPrivateProfileString(_T("Skin_Description_Section"), _T("URL"), _T(""), URL, _countof(URL), sd->File);
				GetPrivateProfileString(_T("Skin_Description_Section"), _T("Contact"), _T(""), Contact, _countof(Contact), sd->File);
				GetPrivateProfileString(_T("Skin_Description_Section"), _T("Description"), _T(""), Description, _countof(Description), sd->File);
				mir_sntprintf(text, TranslateT("%s\n\n%s\n\nAuthor(s):\t %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s"),
					sd->Name, Description, Author, Contact, URL, sd->File);
			}
			else {
				mir_sntprintf(text, TranslateT("%s\n\n%s\n\nAuthor(s): %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s"),
					TranslateT("reVista for Modern v0.5"),
					TranslateT("This is second default Modern Contact list skin in Vista Aero style"),
					TranslateT("Angeli-Ka (graphics), FYR (template)"),
					_T("JID: [email protected]"),
					_T("fyr.mirandaim.ru"),
					TranslateT("Inside library"));
			}
			MessageBox(hwndDlg, text, TranslateT("Skin information"), MB_OK | MB_ICONINFORMATION);
		}
		break;

		case IDC_BUTTON_APPLY_SKIN:
			if (HIWORD(wParam) == BN_CLICKED) {
				SkinListData *sd = NULL;
				HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1));
				if (hti == 0) return 0;
				{
					TVITEM tvi = { 0 };
					tvi.hItem = hti;
					tvi.mask = TVIF_HANDLE | TVIF_PARAM;
					TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi);
					sd = (SkinListData*)(tvi.lParam);
				}
				if (!sd) return 0;
				ske_LoadSkinFromIniFile(sd->File, FALSE);
				ske_LoadSkinFromDB();
				pcli->pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0);
				Sync(CLUIFrames_OnClistResize_mod, 0, 0);
				ske_RedrawCompleteWindow();
				Sync(CLUIFrames_OnClistResize_mod, 0, 0);
				{
					HWND hwnd = pcli->hwndContactList;
					RECT rc = { 0 };
					GetWindowRect(hwnd, &rc);
					Sync(CLUIFrames_OnMoving, hwnd, &rc);
				}
				if (g_hCLUIOptionsWnd) {
					SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_LEFTMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "LeftClientMargin", SETTING_LEFTCLIENTMARIGN_DEFAULT));
					SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_RIGHTMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "RightClientMargin", SETTING_RIGHTCLIENTMARIGN_DEFAULT));
					SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_TOPMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "TopClientMargin", SETTING_TOPCLIENTMARIGN_DEFAULT));
					SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_BOTTOMMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "BottomClientMargin", SETTING_BOTTOMCLIENTMARIGN_DEFAULT));
				}
			}
			break;

		case IDC_BUTTON_RESCAN:
			if (HIWORD(wParam) == BN_CLICKED) {
				HTREEITEM it = FillAvailableSkinList(hwndDlg);
				HWND wnd = GetDlgItem(hwndDlg, IDC_TREE1);
				TreeView_SelectItem(wnd, it);
			}
		}
		break;

	case WM_DRAWITEM:
		if (wParam == IDC_PREVIEW)
		{
			//TODO:Draw hPreviewBitmap here
			int mWidth, mHeight;
			HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
			DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
			mWidth = dis->rcItem.right - dis->rcItem.left;
			mHeight = dis->rcItem.bottom - dis->rcItem.top;
			HDC memDC = CreateCompatibleDC(dis->hDC);
			HBITMAP hbmp = ske_CreateDIB32(mWidth, mHeight);
			HBITMAP holdbmp = (HBITMAP)SelectObject(memDC, hbmp);
			RECT workRect = dis->rcItem;
			OffsetRect(&workRect, -workRect.left, -workRect.top);
			FillRect(memDC, &workRect, hbr);
			DeleteObject(hbr);
			if (hPreviewBitmap)
			{
				//variables
				BITMAP bmp = { 0 };
				POINT imgPos = { 0 };
				float xScale = 1, yScale = 1;
				//GetSize
				GetObject(hPreviewBitmap, sizeof(BITMAP), &bmp);
				int wWidth = workRect.right - workRect.left;
				int wHeight = workRect.bottom - workRect.top;
				if (wWidth < bmp.bmWidth) xScale = (float)wWidth / bmp.bmWidth;
				if (wHeight < bmp.bmHeight) yScale = (float)wHeight / bmp.bmHeight;
				xScale = min(xScale, yScale);
				yScale = xScale;
				int dWidth = (int)(xScale*bmp.bmWidth);
				int dHeight = (int)(yScale*bmp.bmHeight);
				//CalcPosition
				imgPos.x = workRect.left + ((wWidth - dWidth) >> 1);
				imgPos.y = workRect.top + ((wHeight - dHeight) >> 1);
				//DrawImage
				DrawAvatarImageWithGDIp(memDC, imgPos.x, imgPos.y, dWidth, dHeight, hPreviewBitmap, 0, 0, bmp.bmWidth, bmp.bmHeight, 8, 255);
			}
			BitBlt(dis->hDC, dis->rcItem.left, dis->rcItem.top, mWidth, mHeight, memDC, 0, 0, SRCCOPY);
			SelectObject(memDC, holdbmp);
			DeleteObject(hbmp);
			DeleteDC(memDC);
		}
		break;

	case WM_NOTIFY:
		switch (((LPNMHDR)lParam)->idFrom) {
		case IDC_TREE1:
		{
			NMTREEVIEW * nmtv = (NMTREEVIEW *)lParam;
			if (nmtv == NULL)
				return 0;

			if (nmtv->hdr.code == TVN_SELCHANGED) {
				SkinListData * sd = NULL;
				if (hPreviewBitmap) {
					ske_UnloadGlyphImage(hPreviewBitmap);
					hPreviewBitmap = NULL;
				}

				if (nmtv->itemNew.lParam) {
					sd = (SkinListData*)nmtv->itemNew.lParam;

					TCHAR buf[MAX_PATH];
					PathToRelativeT(sd->File, buf);
					SetDlgItemText(hwndDlg, IDC_EDIT_SKIN_FILENAME, buf);

					TCHAR prfn[MAX_PATH] = { 0 }, imfn[MAX_PATH] = { 0 }, skinfolder[MAX_PATH] = { 0 };
					GetPrivateProfileString(_T("Skin_Description_Section"), _T("Preview"), _T(""), imfn, _countof(imfn), sd->File);
					IniParser::GetSkinFolder(sd->File, skinfolder);
					mir_sntprintf(prfn, _T("%s\\%s"), skinfolder, imfn);
					PathToAbsoluteT(prfn, imfn);
					hPreviewBitmap = ske_LoadGlyphImage(imfn);

					EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_APPLY_SKIN), TRUE);
					EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_INFO), TRUE);
					if (hPreviewBitmap)
						InvalidateRect(GetDlgItem(hwndDlg, IDC_PREVIEW), NULL, TRUE);
					else { //prepare text
						TCHAR Author[255], URL[MAX_PATH], Contact[255], Description[400], text[2000];
						SkinListData* sd2 = NULL;
						HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1));
						if (hti == 0) return 0;
						{
							TVITEM tvi = { 0 };
							tvi.hItem = hti;
							tvi.mask = TVIF_HANDLE | TVIF_PARAM;
							TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi);
							sd2 = (SkinListData*)(tvi.lParam);
						}
						if (!sd2) return 0;

						if (sd2->File && !_tcschr(sd2->File, _T('%'))) {
							GetPrivateProfileString(_T("Skin_Description_Section"), _T("Author"), TranslateT("( unknown )"), Author, _countof(Author), sd2->File);
							GetPrivateProfileString(_T("Skin_Description_Section"), _T("URL"), _T(""), URL, _countof(URL), sd2->File);
							GetPrivateProfileString(_T("Skin_Description_Section"), _T("Contact"), _T(""), Contact, _countof(Contact), sd2->File);
							GetPrivateProfileString(_T("Skin_Description_Section"), _T("Description"), _T(""), Description, _countof(Description), sd2->File);
							mir_sntprintf(text, TranslateT("Preview is not available\n\n%s\n----------------------\n\n%s\n\nAUTHOR(S):\n%s\n\nCONTACT:\n%s\n\nHOMEPAGE:\n%s"),
								sd2->Name, Description, Author, Contact, URL);
						}
						else {
							mir_sntprintf(text, TranslateT("%s\n\n%s\n\nAUTHORS:\n%s\n\nCONTACT:\n%s\n\nWEB:\n%s\n\n\n"),
								TranslateT("reVista for Modern v0.5"),
								TranslateT("This is second default Modern Contact list skin in Vista Aero style"),
								TranslateT("graphics by Angeli-Ka\ntemplate by FYR"),
								_T("JID: [email protected]"),
								_T("fyr.mirandaim.ru"));
						}
						ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), SW_HIDE);
						ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_INFO), SW_SHOW);
						SetDlgItemText(hwndDlg, IDC_STATIC_INFO, text);
					}
				}
				else {
					//no selected
					SetDlgItemText(hwndDlg, IDC_EDIT_SKIN_FILENAME, TranslateT("Select skin from list"));
					EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_APPLY_SKIN), FALSE);
					EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_INFO), FALSE);
					SetDlgItemText(hwndDlg, IDC_STATIC_INFO, TranslateT("Please select skin to apply"));
					ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), SW_HIDE);
				}
				ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), hPreviewBitmap ? SW_SHOW : SW_HIDE);
				return 0;
			}
			else if (nmtv->hdr.code == TVN_DELETEITEM) {
				mir_free_and_nil(nmtv->itemOld.lParam);
				return 0;
			}
		}
		break;

		case 0:
			switch (((LPNMHDR)lParam)->code) {
			case PSN_APPLY:
				pcli->pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0);
				NotifyEventHooks(g_CluiData.hEventBkgrChanged, 0, 0);
				pcli->pfnClcBroadcast(INTM_INVALIDATE, 0, 0);
				RedrawWindow(GetParent(pcli->hwndContactTree), NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
			}
			break;
		}
	}
void Cache_ProceedAvatarInList(struct ClcData *dat, struct ClcContact *contact)
{
	struct avatarCacheEntry * ace=contact->avatar_data;
	int old_pos=contact->avatar_pos;

	if (   ace==NULL 
		|| ace->dwFlags == AVS_BITMAP_EXPIRED
		|| ace->hbmPic == NULL)
	{
		//Avatar was not ready or removed - need to remove it from cache
		if (old_pos>=0)
		{
			ImageArray_RemoveImage(&dat->avatar_cache, old_pos);
			// Update all items
			ExecuteOnAllContacts(dat, ReduceAvatarPosition, (void *)&old_pos);
			contact->avatar_pos=AVATAR_POS_DONT_HAVE;
			return;
		}
	}
	else if (contact->avatar_data->hbmPic != NULL) //Lets Add it
	{
		HDC hdc; 
		HBITMAP hDrawBmp,oldBmp;
		void * pt;

		// Make bounds -> keep aspect radio
		LONG width_clip;
		LONG height_clip;
		RECT rc = {0};

		// Clipping width and height
		width_clip = dat->avatars_maxwidth_size?dat->avatars_maxwidth_size:dat->avatars_maxheight_size;
		height_clip = dat->avatars_maxheight_size;

		if (height_clip * ace->bmWidth / ace->bmHeight <= width_clip)
		{
			width_clip = height_clip * ace->bmWidth / ace->bmHeight;
		}
		else
		{
			height_clip = width_clip * ace->bmHeight / ace->bmWidth;					
		}
		if (wildcmpi(contact->avatar_data->szFilename,_T("*.gif")))
		{
			int res;
			if (old_pos==AVATAR_POS_ANIMATED)
				AniAva_RemoveAvatar(contact->hContact);

			res=AniAva_AddAvatar(contact->hContact, contact->avatar_data->szFilename, width_clip, height_clip);
			if (res)
			{
				contact->avatar_pos=AVATAR_POS_ANIMATED;
				contact->avatar_size.cy=HIWORD(res);
				contact->avatar_size.cx=LOWORD(res);
				return;
			}
		}
		// Create objs
		hdc = CreateCompatibleDC(dat->avatar_cache.hdc); 
		hDrawBmp = ske_CreateDIB32Point(width_clip, height_clip,&pt);
		oldBmp=(HBITMAP)SelectObject(hdc, hDrawBmp);
		//need to draw avatar bitmap here
		{
			RECT real_rc={0,0,width_clip, height_clip};
			/*
			if (ServiceExists(MS_AV_BLENDDRAWAVATAR))
			{
				AVATARDRAWREQUEST adr;

				adr.cbSize = sizeof(AVATARDRAWREQUEST);
				adr.hContact = contact->hContact;
				adr.hTargetDC = hdc;
				adr.rcDraw = real_rc;
				adr.dwFlags = 0;				
				adr.alpha = 255;
				CallService(MS_AV_BLENDDRAWAVATAR, 0, (LPARAM) &adr);
			}
			else
			*/
			{
				int w=width_clip;
				int h=height_clip;
				if (!g_CluiData.fGDIPlusFail) //Use gdi+ engine
				{
					DrawAvatarImageWithGDIp(hdc, 0, 0, w, h,ace->hbmPic,0,0,ace->bmWidth,ace->bmHeight,ace->dwFlags,255);
				}
				else
				{
					if (!(ace->dwFlags&AVS_PREMULTIPLIED))
					{
						HDC hdcTmp = CreateCompatibleDC(hdc);
						RECT r={0,0,w,h};
						HDC hdcTmp2 = CreateCompatibleDC(hdc);
						HBITMAP bmo=(HBITMAP)SelectObject(hdcTmp,ace->hbmPic);
						HBITMAP b2=ske_CreateDIB32(w,h);
						HBITMAP bmo2=(HBITMAP)SelectObject(hdcTmp2,b2);
						SetStretchBltMode(hdcTmp,  HALFTONE);
						SetStretchBltMode(hdcTmp2,  HALFTONE);
						StretchBlt(hdcTmp2, 0, 0, w, h,
							hdcTmp, 0, 0, ace->bmWidth, ace->bmHeight,
							SRCCOPY);

						ske_SetRectOpaque(hdcTmp2,&r);
						BitBlt(hdc, rc.left, rc.top, w, h,hdcTmp2,0,0,SRCCOPY);
						SelectObject(hdcTmp2,bmo2);
						SelectObject(hdcTmp,bmo);
						mod_DeleteDC(hdcTmp);
						mod_DeleteDC(hdcTmp2);
						DeleteObject(b2);
					}
					else {
						BLENDFUNCTION bf={AC_SRC_OVER, 0,255, AC_SRC_ALPHA };
						HDC hdcTempAv = CreateCompatibleDC(hdc);
						HBITMAP hbmTempAvOld;
						hbmTempAvOld = (HBITMAP)SelectObject(hdcTempAv,ace->hbmPic);
						ske_AlphaBlend(hdc, rc.left, rc.top, w, h, hdcTempAv, 0, 0,ace->bmWidth,ace->bmHeight, bf);
						SelectObject(hdcTempAv, hbmTempAvOld);
						mod_DeleteDC(hdcTempAv);
					}
				}
			}
		}
		SelectObject(hdc,oldBmp);
		DeleteDC(hdc);
		// Add to list
		if (old_pos >= 0)
		{
			ImageArray_ChangeImage(&dat->avatar_cache, hDrawBmp, old_pos);
			contact->avatar_pos = old_pos;
		}
		else
		{
			contact->avatar_pos = ImageArray_AddImage(&dat->avatar_cache, hDrawBmp, -1);
		}
		if (old_pos==AVATAR_POS_ANIMATED && contact->avatar_pos!=AVATAR_POS_ANIMATED)
		{
			AniAva_RemoveAvatar(contact->hContact);
		}

		DeleteObject(hDrawBmp);

	}

}
INT_PTR CALLBACK DlgSkinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch ( msg )
	{
	case WM_DESTROY: 
		{
			if ( hPreviewBitmap ) ske_UnloadGlyphImage( hPreviewBitmap );
			break;
		}

	case WM_INITDIALOG:
		{ 
			HTREEITEM it;
			TranslateDialogDefault( hwndDlg );
			it = FillAvailableSkinList( hwndDlg );
			HWND wnd = GetDlgItem( hwndDlg, IDC_TREE1 );
			TreeView_SelectItem( wnd, it );						
		}
		return 0;
	case WM_COMMAND:
		{
			int isLoad = 0;
			switch ( LOWORD( wParam ) ) 
			{
			case IDC_COLOUR_MENUNORMAL:
			case IDC_COLOUR_MENUSELECTED:
			case IDC_COLOUR_FRAMES:
			case IDC_COLOUR_STATUSBAR:
				SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
				break;

			case IDC_BUTTON_INFO:
				{
					TCHAR Author[255];
					TCHAR URL[MAX_PATH];
					TCHAR Contact[255];
					TCHAR Description[400];
					TCHAR text[2000];
					SkinListData *sd = NULL;  
					HTREEITEM hti = TreeView_GetSelection( GetDlgItem( hwndDlg, IDC_TREE1 ) );				
					if ( hti == 0 ) return 0;
					{
						TVITEM tvi = {0};
						tvi.hItem = hti;
						tvi.mask = TVIF_HANDLE|TVIF_PARAM;
						TreeView_GetItem( GetDlgItem( hwndDlg, IDC_TREE1 ), &tvi );
						sd = ( SkinListData* )( tvi.lParam );
					}
					if ( !sd ) return 0;
					if ( sd->File && !_tcschr( sd->File, _T('%') ) )
					{
						GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Author" ), 	TranslateT( "( unknown )" ), 	Author, 		SIZEOF( Author ), 		sd->File );
						GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "URL" ), 		_T( "" ), 						URL, 		SIZEOF( URL ), 		sd->File );
						GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Contact" ), 	_T( "" ), 						Contact, 	SIZEOF( Contact ), 	sd->File );
						GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Description" ), _T( "" ), 					Description, SIZEOF( Description ), sd->File );
						_sntprintf( text, SIZEOF( text ), TranslateT( "%s\n\n%s\n\nAuthor(s):\t %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s" ), 
							sd->Name, Description, Author, Contact, URL, sd->File );
					}
					else
					{
						_sntprintf( text, SIZEOF( text ), TranslateT( "%s\n\n%s\n\nAuthor(s): %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s" ), 
							TranslateT( "reVista for Modern v0.5" ), 
							TranslateT( "This is second default Modern Contact list skin in Vista Aero style" ), 
							TranslateT( "Angeli-Ka (graphics), FYR (template)" ), 
							_T( "JID: [email protected]" ), 
							_T("fyr.mirandaim.ru"), 
							TranslateT( "Inside library" ) );
					}
					MessageBox( hwndDlg, text, TranslateT( "Skin Information" ), MB_OK|MB_ICONINFORMATION );
				}
				break;
			case IDC_BUTTON_APPLY_SKIN:
				if ( HIWORD( wParam ) == BN_CLICKED )
				{ 		
					SkinListData *sd = NULL;  
					HTREEITEM hti = TreeView_GetSelection( GetDlgItem( hwndDlg, IDC_TREE1 ) );				
					if ( hti == 0 ) return 0;
					{
						TVITEM tvi = {0};
						tvi.hItem = hti;
						tvi.mask = TVIF_HANDLE|TVIF_PARAM;
						TreeView_GetItem( GetDlgItem( hwndDlg, IDC_TREE1 ), &tvi );
						sd = ( SkinListData* )( tvi.lParam );
					}
					if ( !sd ) return 0;
					if ( glSkinWasModified>0 )
					{
						int res = 0;
						if ( glSkinWasModified == 1 )
							res = MessageBox( hwndDlg, TranslateT( "Skin editor contains not stored changes.\n\nAll changes will be lost.\n\n Continue to load new skin?" ), TranslateT( "Warning!" ), MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2|MB_TOPMOST );
						else
							res = MessageBox( hwndDlg, TranslateT( "Current skin was not saved to file.\n\nAll changes will be lost.\n\n Continue to load new skin?" ), TranslateT( "Warning!" ), MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2|MB_TOPMOST );
						if ( res!= IDOK ) return 0;
					}
					ske_LoadSkinFromIniFile( sd->File, FALSE );
					ske_LoadSkinFromDB( );	
					glOtherSkinWasLoaded = TRUE;
					pcli->pfnClcBroadcast( INTM_RELOADOPTIONS, 0, 0 );
					Sync( CLUIFrames_OnClistResize_mod, 0, 0 );
					ske_RedrawCompleteWindow( );        
					Sync( CLUIFrames_OnClistResize_mod, 0, 0 );
					{
						HWND hwnd = pcli->hwndContactList;
						RECT rc = {0};
						GetWindowRect( hwnd, &rc );
						Sync( CLUIFrames_OnMoving, hwnd, &rc );
					}
					if ( g_hCLUIOptionsWnd )
					{
						SendDlgItemMessage( g_hCLUIOptionsWnd, IDC_LEFTMARGINSPIN, UDM_SETPOS, 0, ModernGetSettingByte( NULL, "CLUI", "LeftClientMargin", SETTING_LEFTCLIENTMARIGN_DEFAULT ) );
						SendDlgItemMessage( g_hCLUIOptionsWnd, IDC_RIGHTMARGINSPIN, UDM_SETPOS, 0, ModernGetSettingByte( NULL, "CLUI", "RightClientMargin", SETTING_RIGHTCLIENTMARIGN_DEFAULT ) );
						SendDlgItemMessage( g_hCLUIOptionsWnd, IDC_TOPMARGINSPIN, UDM_SETPOS, 0, ModernGetSettingByte( NULL, "CLUI", "TopClientMargin", SETTING_TOPCLIENTMARIGN_DEFAULT ) );
						SendDlgItemMessage( g_hCLUIOptionsWnd, IDC_BOTTOMMARGINSPIN, UDM_SETPOS, 0, ModernGetSettingByte( NULL, "CLUI", "BottomClientMargin", SETTING_BOTTOMCLIENTMARIGN_DEFAULT ) );
					}
				}
				break;
			case IDC_BUTTON_LOAD:
				isLoad = 1;
				if ( HIWORD( wParam ) == BN_CLICKED )
				{
					{   		
						TCHAR str[MAX_PATH] = {0};
						OPENFILENAME ofn = {0};
						TCHAR filter[512] = {0};
						int res = 0;
						ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
						ofn.hwndOwner = hwndDlg;
						ofn.hInstance = NULL;

						mir_sntprintf(filter, SIZEOF(filter), _T("%s (*.msf)%c*.MSF%c%c"), TranslateT("Miranda skin file"), 0, 0, 0);
						ofn.lpstrFilter = filter;
						ofn.lpstrFile = str;
						ofn.Flags = isLoad?( OFN_FILEMUSTEXIST | OFN_HIDEREADONLY ) : ( OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY ) | OFN_DONTADDTORECENT;
						ofn.nMaxFile = sizeof( str );
						ofn.nMaxFileTitle = MAX_PATH;
						ofn.lpstrDefExt = _T( "msf" );

						{
							DWORD tick = GetTickCount( );
							res = GetOpenFileName( &ofn );
							if( !res ) 
								if ( GetTickCount( )-tick<100 )
								{
									res = GetOpenFileName( &ofn );
									if( !res ) break;
								}
								else break;
						}
						if ( res )
						{
							HTREEITEM it = AddSkinToListFullName( hwndDlg, ofn.lpstrFile );
							TreeView_SelectItem( GetDlgItem( hwndDlg, IDC_TREE1 ), it );
							//SendDlgItemMessage( hwndDlg, IDC_SKINS_LIST, LB_SETCURSEL, it, 0 ); 
							//SendMessage( hwndDlg, WM_COMMAND, MAKEWPARAM( IDC_SKINS_LIST, LBN_SELCHANGE ), 0 );
						}
					}
				}
			}
			break;
		}
	case WM_DRAWITEM:
		if ( wParam == IDC_PREVIEW )
		{
			//TODO:Draw hPreviewBitmap here
			HDC memDC, imgDC;
			HBITMAP hbmp, holdbmp, imgOldbmp;
			int mWidth, mHeight;
			RECT workRect = {0};
			HBRUSH hbr = CreateSolidBrush( GetSysColor( COLOR_3DFACE ) );
			DRAWITEMSTRUCT *dis = ( DRAWITEMSTRUCT * )lParam;
			mWidth = dis->rcItem.right-dis->rcItem.left;
			mHeight = dis->rcItem.bottom-dis->rcItem.top;
			memDC = CreateCompatibleDC( dis->hDC );
			hbmp = ske_CreateDIB32( mWidth, mHeight );
			holdbmp = ( HBITMAP )SelectObject( memDC, hbmp );
			workRect = dis->rcItem;
			OffsetRect( &workRect, -workRect.left, -workRect.top );
			FillRect( memDC, &workRect, hbr );     
			DeleteObject( hbr );
			if ( hPreviewBitmap )
			{
				//variables
				BITMAP bmp = {0};
				POINT imgPos = {0};
				int wWidth, wHeight;
				int dWidth, dHeight;
				float xScale = 1, yScale = 1;
				//GetSize
				GetObject( hPreviewBitmap, sizeof( BITMAP ), &bmp );
				wWidth = workRect.right-workRect.left;
				wHeight = workRect.bottom-workRect.top;
				if ( wWidth<bmp.bmWidth ) xScale = ( float )wWidth/bmp.bmWidth;
				if ( wHeight<bmp.bmHeight ) yScale = ( float )wHeight/bmp.bmHeight;
				xScale = min( xScale, yScale );
				yScale = xScale;                    
				dWidth = ( int )( xScale*bmp.bmWidth );
				dHeight = ( int )( yScale*bmp.bmHeight );
				//CalcPosition
				imgPos.x = workRect.left+( ( wWidth-dWidth )>>1 );
				imgPos.y = workRect.top+( ( wHeight-dHeight )>>1 );     
				//DrawImage
				if ( !g_CluiData.fGDIPlusFail ) //Use gdi+ engine
				{
					DrawAvatarImageWithGDIp( memDC, imgPos.x, imgPos.y, dWidth, dHeight, hPreviewBitmap, 0, 0, bmp.bmWidth, bmp.bmHeight, 8, 255 );
				}   
				else
				{
					BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
					imgDC = CreateCompatibleDC( dis->hDC );
					imgOldbmp = ( HBITMAP )SelectObject( imgDC, hPreviewBitmap );                 
					ske_AlphaBlend( memDC, imgPos.x, imgPos.y, dWidth, dHeight, imgDC, 0, 0, bmp.bmWidth, bmp.bmHeight, bf );
					SelectObject( imgDC, imgOldbmp );
					mod_DeleteDC( imgDC );
				}
			}
			BitBlt( dis->hDC, dis->rcItem.left, dis->rcItem.top, mWidth, mHeight, memDC, 0, 0, SRCCOPY );
			SelectObject( memDC, holdbmp );
			DeleteObject( hbmp );
			mod_DeleteDC( memDC );
		}
		break;

	case WM_NOTIFY:
		switch ( ( ( LPNMHDR )lParam )->idFrom ) 
		{
		case IDC_TREE1:
			{		
				NMTREEVIEW * nmtv = ( NMTREEVIEW * ) lParam;
				if ( !nmtv ) return 0;
				if ( nmtv->hdr.code == TVN_SELCHANGEDA
					|| nmtv->hdr.code == TVN_SELCHANGEDW )
				{	
					SkinListData * sd = NULL;
					if ( hPreviewBitmap ) 
					{
						ske_UnloadGlyphImage( hPreviewBitmap );
						hPreviewBitmap = NULL;
					}
					if ( nmtv->itemNew.lParam )
					{
						sd = ( SkinListData* )nmtv->itemNew.lParam;
						{
							TCHAR buf[MAX_PATH];
							CallService( MS_UTILS_PATHTORELATIVET, ( WPARAM )sd->File, ( LPARAM )buf );
							SendDlgItemMessage( hwndDlg, IDC_EDIT_SKIN_FILENAME, WM_SETTEXT, 0, ( LPARAM )buf );
						}
						{
							TCHAR prfn[MAX_PATH] = {0};
							TCHAR imfn[MAX_PATH] = {0};
							TCHAR skinfolder[MAX_PATH] = {0};
							GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Preview" ), _T( "" ), imfn, SIZEOF( imfn ), sd->File );
							IniParser::GetSkinFolder( sd->File, skinfolder );
							_sntprintf( prfn, SIZEOF( prfn ), _T("%s\\%s"), skinfolder, imfn );
							CallService( MS_UTILS_PATHTOABSOLUTET, ( WPARAM )prfn, ( LPARAM ) imfn );
							char * imfn_ch = mir_t2a( imfn ); 
							hPreviewBitmap = ske_LoadGlyphImage( imfn_ch );
							mir_free( imfn_ch );
						}
						EnableWindow( GetDlgItem( hwndDlg, IDC_BUTTON_APPLY_SKIN ), TRUE );
						EnableWindow( GetDlgItem( hwndDlg, IDC_BUTTON_INFO ), TRUE );
						if ( hPreviewBitmap ) 
							InvalidateRect( GetDlgItem( hwndDlg, IDC_PREVIEW ), NULL, TRUE );
						else  //prepare text
						{
							TCHAR Author[255];
							TCHAR URL[MAX_PATH];
							TCHAR Contact[255];
							TCHAR Description[400];
							TCHAR text[2000];
							SkinListData* sd = NULL;
							HTREEITEM hti = TreeView_GetSelection( GetDlgItem( hwndDlg, IDC_TREE1 ) );				
							if ( hti == 0 ) return 0;
							{
								TVITEM tvi = {0};
								tvi.hItem = hti;
								tvi.mask = TVIF_HANDLE|TVIF_PARAM;
								TreeView_GetItem( GetDlgItem( hwndDlg, IDC_TREE1 ), &tvi );
								sd = ( SkinListData* )( tvi.lParam );
							}
							if ( !sd ) return 0;

							if( sd->File && !_tcschr( sd->File, _T('%') ) )
							{
								GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Author" ), 	TranslateT( "( unknown )" ), 	Author, 		SIZEOF( Author ), 		sd->File );
								GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "URL" ), 		_T( "" ), 						URL, 		SIZEOF( URL ), 		sd->File );
								GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Contact" ), 	_T( "" ), 						Contact, 	SIZEOF( Contact ), 	sd->File );
								GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Description" ), _T( "" ), 					Description, SIZEOF( Description ), sd->File );
								_sntprintf( text, SIZEOF( text ), TranslateT( "Preview is not available\n\n%s\n----------------------\n\n%s\n\nAUTHOR(S):\n%s\n\nCONTACT:\n%s\n\nHOMEPAGE:\n%s" ), 
									sd->Name, Description, Author, Contact, URL );
							}
							else
							{
								_sntprintf( text, SIZEOF( text ), TranslateT( "%s\n\n%s\n\nAUTHORS:\n%s\n\nCONTACT:\n%s\n\nWEB:\n%s\n\n\n" ), 
									TranslateT( "reVista for Modern v0.5" ), 
									TranslateT( "This is second default Modern Contact list skin in Vista Aero style" ), 
									TranslateT( "graphics by Angeli-Ka\ntemplate by FYR" ), 
									_T("JID: [email protected]"), 
									_T("fyr.mirandaim.ru") );
							}
							ShowWindow( GetDlgItem( hwndDlg, IDC_PREVIEW ), SW_HIDE );
							ShowWindow( GetDlgItem( hwndDlg, IDC_STATIC_INFO ), SW_SHOW );
							SendDlgItemMessage( hwndDlg, IDC_STATIC_INFO, WM_SETTEXT, 0, ( LPARAM )text );
						}					
					}
					else
					{
						//no selected
						SendDlgItemMessage( hwndDlg, IDC_EDIT_SKIN_FILENAME, WM_SETTEXT, 0, ( LPARAM )TranslateT( "Select skin from list" ) );
						EnableWindow( GetDlgItem( hwndDlg, IDC_BUTTON_APPLY_SKIN ), FALSE );
						EnableWindow( GetDlgItem( hwndDlg, IDC_BUTTON_INFO ), FALSE );
						SendDlgItemMessage( hwndDlg, IDC_STATIC_INFO, WM_SETTEXT, 0, ( LPARAM )TranslateT( "Please select skin to apply" ) );
						ShowWindow( GetDlgItem( hwndDlg, IDC_PREVIEW ), SW_HIDE );
					}
					ShowWindow( GetDlgItem( hwndDlg, IDC_PREVIEW ), hPreviewBitmap?SW_SHOW:SW_HIDE );
					return 0;
				}			
				else if ( nmtv->hdr.code == TVN_DELETEITEMA || nmtv->hdr.code == TVN_DELETEITEMW )
				{
					if ( nmtv->itemOld.lParam )
						mir_free_and_nill( nmtv->itemOld.lParam );
					return 0;
				}
				break;
			}
		case 0:
			switch ( ( ( LPNMHDR )lParam )->code )
			{
			case PSN_APPLY:
				{
					{
						DWORD tick = GetTickCount( );
						pcli->pfnClcBroadcast( INTM_RELOADOPTIONS, 0, 0 );
						NotifyEventHooks( g_CluiData.hEventBkgrChanged, 0, 0 );
						pcli->pfnClcBroadcast( INTM_INVALIDATE, 0, 0 );	
						RedrawWindow( GetParent( pcli->hwndContactTree ), NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_ALLCHILDREN );
					}
					return 0;
				}
				break;
			}
			break;
		}
	}