Автор: Maks150988
Дата сообщения: 06.12.2008 08:36
ShIvADeSt
Ну то есть имеется 32-битная картинка, где есть альфа канал еще, а может мы имеем такую же иконку. Рисунок на ней круглый, а все остальное прозрачно. Например можно создать ImageList из 4 картинок в одной для 4 состояний кнопки. А уже изображения для кнопки из него вытягивать через функцию ImageList_GetIcon и потом через DrawIconEx отображать. Проблема то в том что если уже натянут на диалог рисунок, а тут мы отображаем иконку из списка изображений - видно "квадрат" кнопки. Это ж получается само окно то кнопки не закруглено опять же. Хотел попробовать через овнердрав статика, но там не приходят ODS сообщения в дравитеме и через трекмаусевент тоже не получилось (а может я опять что-то напутал в спешке когджа код переделывал).
Мне видится такой вариант - просчитывать координаты на основном диалоге и через PtInRect проверять их и уже просто в WM_PAINT после накладывания основго рисунка для диалога выводить значок нужный через DrawIconEx. нО это конечно мудрено все, нет ли варианта попроще?
Сделал со стактиком такой код, проверил чтоб было ODT_STATIC в WM_DRAWITEM. Блин, такое ощущение что не изменяется толком сообщение ODT для контрола. Или этот ODS_SELECTED не работает в статике системном... И ведь пробовал еще сабклассингом делать булевую переменную подставлять и вслучае изменения подставлять в DrawIconEx нужный значок, но ничего не менялось, решил поэтому опробовать на DrawTextW. То же самое. Где ошибка, не подскажете?
[more=>>>]program skincore;
uses
Windows, Messages, CommCtrl;
const
szClassName = 'VanillaClass';
RC_BUTTON_PLAY = 102;
var
hApp : THandle;
szSkinPath : WideString;
hInstanceW : Thandle;
hImLst : HIMAGELIST;
hImBmp : HBITMAP;
MouseOver_ :hIcon;
PlayIsMouse:Boolean;
PlayBtnProc:Pointer;
procedure CenterWindow(hWindow: THandle);
var
WndRect : TRect;
iWidth : Integer;
iHeight : Integer;
begin
GetWindowRect(hWindow, WndRect);
iWidth := WndRect.Right - WndRect.Left;
iHeight := WndRect.Bottom - WndRect.Top;
WndRect.Left := (GetSystemMetrics(SM_CXSCREEN) - iWidth) div 2;
WndRect.Top := (GetSystemMetrics(SM_CYSCREEN) - iHeight) div 2;
MoveWindow(hWindow, WndRect.Left, WndRect.Top, iWidth, iHeight, FALSE);
end;
{}
procedure PaintImageFileButton(DC: HDC; Rect: TRect; szPathFile: WideString);
var
NewBmp: HBITMAP;
OldBmp: HBITMAP;
CompDC: HDC;
begin
CompDC := CreateCompatibleDC(0);
NewBmp := LoadImageW(0, PWideChar(szPathFile), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
OldBmp := SelectObject(CompDC, NewBmp);
BitBlt(DC, 0, 0, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top, CompDC, 0, 0, SRCCOPY);
SelectObject(CompDC, OldBmp);
DeleteDC(CompDC);
DeleteObject(NewBmp);
end;
{}
procedure GetBitmapRect(szPathFile: WideString; var plRect: TRect);
var
Bitmap: HBITMAP;
bInfo : TBitmapInfo;
begin
Bitmap := LoadImageW(0, PWideChar(szPathFile), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(Bitmap, SizeOf(bInfo), @bInfo);
plRect.Right := bInfo.bmiHeader.biWidth;
plRect.Bottom := bInfo.bmiHeader.biHeight;
DeleteObject(Bitmap);
end;
function DrawPlayButton(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
lpPoint: TPoint;
lpRect : TRect;
begin
case uMsg of
WM_MOUSEMOVE:
begin
GetCursorPos(lpPoint);
GetWindowRect(hWnd, lpRect);
if PtInRect(lpRect, lpPoint) then
begin
if GetCapture <> hWnd then
begin
SetCapture(hWnd);
PlayIsMouse := TRUE;
end;
end
else
begin
ReleaseCapture;
PlayIsMouse := FALSE;
end;
InvalidateRect(hWnd, nil, FALSE);
end;
end;
Result := CallWindowProcW(PlayBtnProc, hWnd, uMsg, wParam, lParam);
end;
{}
function MainWndProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
lpRect : TRect;
lpPaint: TPaintStruct;
lpdis : PDrawItemStruct;
begin
Result := 0;
case uMsg of
{}
WM_CREATE:
begin
hApp := hWnd;
{ устанавливаем путь к директории с файлами для оболочки }
szSkinPath := WideString(ExtractFilePathW(ParamStrW)) + 'images' + '\';
{ загружаем настройки оболочки для отображения картинок на окнах }
GetBitmapRect(WideString(szSkinPath + 'main_window_normal.bmp'), lpRect);
SetWindowLongW(hApp, GWL_EXSTYLE, GetWindowLong(hApp, GWL_EXSTYLE) or WS_EX_LAYERED);
SetLayeredWindowAttributes(hApp, RGB(255, 0, 255), (255 * 85) div 100, LWA_COLORKEY + LWA_ALPHA);
SetWindowPos(hApp, 0, 0, 0, lpRect.Right, lpRect.Bottom, SWP_NOZORDER);
{}
GetBitmapRect(WideString(szSkinPath + 'play_button_normal.bmp'), lpRect);
CreateWindowExW(0, 'STATIC', '', SS_OWNERDRAW or WS_CHILD or WS_VISIBLE or WS_TABSTOP, 85, 32, lpRect.Right, lpRect.Bottom, hApp, RC_BUTTON_PLAY, hInstanceW, nil);
{ создаем список с изображениями }
hImBmp := LoadImageW(0, PWideChar(WideString(ExtractFilePathW(ParamStrW)) + 'testbmp.bmp'), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
hImLst := ImageList_Create(lpRect.Right, lpRect.Bottom, ILC_COLOR32, 4, 0);
ImageList_Add(hImLst, hImBmp, hImBmp);
//ImageList_SetBkColor(hImLst, RGB(255, 0, 255));
//MouseOver := ImageList_GetIcon(hImLst, 1, ILD_NORMAL);
PlayBtnProc := Pointer(GetWindowLongW(GetDlgItem(hApp, RC_BUTTON_PLAY), GWL_WNDPROC));
SetWindowLongW(GetDlgItem(hApp, RC_BUTTON_PLAY), GWL_WNDPROC, LongInt(@DrawPlayButton));
{ создаем регионы для окон кнопок }
// BitmapToRegion(GetDlgItem(hApp, RC_BUTTON_PLAY), WideString(ExtractFilePathW(ParamStrW) + 'testbmp.bmp'), TRUE);
CenterWindow(hApp);
end;
{}
WM_PAINT:
begin
//
BeginPaint(hApp, lpPaint);
GetClientRect(hApp, lpRect);
PaintImageFileButton(lpPaint.hDC, lpRect, WideString(szSkinPath + 'main_window_normal.bmp'));
EndPaint(hApp, lpPaint);
//
// BeginPaint(GetDlgItem(hApp, RC_BUTTON_PLAY), lpPaint);
// GetClientRect(GetDlgItem(hApp, RC_BUTTON_PLAY), lpRect);
// if PlayIsMouse then
// begin
// DrawIconEx(lpPaint.hDC, lpRect.Left, lpRect.Top, PlayIsMouse, 46, 46, 0, 0, DI_NORMAL);
// DrawTextW(lpPaint.hDC, PWideChar(WideString('yes')), -1, lpRect, DT_LEFT or DT_WORDBREAK or DT_VCENTER);
// end
// else
// begin
// DrawIconEx(lpPaint.hDC, lpRect.Left, lpRect.Top, ImageList_GetIcon(hImLst, 0, ILD_NORMAL), 46, 46, 0, 0, DI_NORMAL);
// DrawTextW(lpPaint.hDC, PWideChar(WideString('not')), -1, lpRect, DT_LEFT or DT_WORDBREAK or DT_VCENTER);
// end;
// EndPaint(GetDlgItem(hApp, RC_BUTTON_PLAY), lpPaint);
//
//Result := 0;
end;
{}
WM_DRAWITEM:
begin
lpdis := PDrawItemStruct(lParam);
case lpdis.CtlType of
ODT_STATIC:
begin
case lpdis.CtlID of
RC_BUTTON_PLAY:
begin
if (lpdis.itemState and ODS_SELECTED) <> 0 then
DrawTextW(lpdis.hDC, PWideChar(WideString('press')), -1, lpdis.rcItem, DT_LEFT or DT_WORDBREAK or DT_VCENTER)
else
DrawTextW(lpdis.hDC, PWideChar(WideString('normal')), -1, lpdis.rcItem, DT_LEFT or DT_WORDBREAK or DT_VCENTER);
// if PlayIsMouse and not ((lpdis.itemState and ODS_SELECTED) <> 0) then
// DrawTextW(lpdis.hDC, PWideChar(WideString('hover')), -1, lpdis.rcItem, DT_LEFT or DT_WORDBREAK or DT_VCENTER);
// if (lpdis.itemState and ODS_DISABLED) <> 0 then
// DrawTextW(lpdis.hDC, PWideChar(WideString('disable')), -1, lpdis.rcItem, DT_LEFT or DT_WORDBREAK or DT_VCENTER);
end;
end;
end;
end;
end;
{}
WM_CLOSE, WM_DESTROY:
begin
DeleteObject(hImLst);
PostQuitMessage(0);
end;
{}
else
Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
end;
end;
var
wCls: TWndClassExW;
uMsg: TMsg;
hDlg: Thandle;
begin
InitCommonControls;
hInstanceW := GetModuleHandleW(nil);
ZeroMemory(@wCls, SizeOf(wCls));
wCls.cbSize := SizeOf(TWndClassExW);
wCls.style := CS_HREDRAW or CS_VREDRAW;
wCls.lpfnWndProc := @MainWndProc;
wCls.cbClsExtra := 0;
wCls.cbWndExtra := 0;
wCls.hInstance := hInstanceW;
wCls.hIcon := 0;
wCls.hCursor := LoadImageW(0, PWideChar(IDC_ARROW), IMAGE_CURSOR, 16, 16, LR_LOADTRANSPARENT or LR_SHARED);
wCls.hbrBackground := COLOR_BTNFACE + 1;
wCls.lpszMenuName := nil;
wCls.lpszClassName := szClassName;
RegisterClassExW(wCls);
hDlg := CreateWindowExW(WS_EX_LAYERED or WS_EX_TOOLWINDOW or WS_EX_TOPMOST, PWideChar(WideString(szClassName)), PWideChar(WideString(szClassName)), WS_POPUP or WS_SYSMENU or WS_OVERLAPPED or WS_SYSMENU, Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), 0, 0, 0, 0, hInstanceW, nil);
ShowWindow(hDlg, SW_SHOWNORMAL);
UpdateWindow(hDlg);
while GetMessageW(uMsg, 0, 0, 0) do
if not (IsDialogMessageW(hDlg, uMsg)) then
begin
TranslateMessage(uMsg);
DispatchMessageW(uMsg);
end;
UnRegisterClassW(wCls.lpszClassName, hInstanceW);
DestroyWindow(hDlg);
//ExitCode := uMsg.wParam;
end.[/more]