![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ownerdraw Button Control и region'ы
Nick Denry © (2005-09-09 15:56:00)Народ подскажите , плиз, почему кнопка (обычный 'Button' class) не изменяет свою форму, если установить ей регион? Может имеет смысл ее сабклассировать, чтобы перехватывать какие то ее собщения?
Игорь Шевченко (2005-09-09 17:26:00) [21]Nick Denry © (09.09.05 17:15) [5]
> Игорь, объясни плиз в чем тут клиентские и оконные координаты?
Вообще-то оконная координата левого верхнего угла окна равна нулю.
Nick Denry (2005-09-09 17:15:00) [22]Button1 := CreateWindow('BUTTON','_OK_', WS_CHILD or WS_VISIBLE or BS_OWNERDRAW, 10, 10, 70, 25, MainWnd, 0, HInstance, nil);
btnRgn := CreateEllipticRgn(10,10,30,25);
??
Игорь, объясни плиз в чем тут клиентские и оконные координаты?
имхо же все в оконных идет?
Игорь Шевченко (2005-09-09 17:07:00) [23]"The coordinates of a window's window region are relative to the upper-left corner of the window, not the client area of the window. "
Nick Denry (2005-09-09 16:49:00) [24]Я думал - может Parent - окно не перерисовывается, но оно вроде как перерисовывается...
прочем чего мелочиться - вот весь код:
Program test;
uses
windows,
messages;
var
wc : TWndClassEx; //Переменная шаблона класса окна
MainWnd : HWND; //Описатель главного окна
Mesg : TMsg; //Переменная для цикла сбора сообщений
Button1 : HWND;
btnRgn : HRGN;
bmpUp, bmpDwn : HBITMAP;
function GetRootDir : String;
var
i : Integer;
lpszExeDirPath : string;
begin
lpszExeDirPath := ParamStr(0);
for i := Length(lpszExeDirPath) downto 0 do
begin
if lpszExeDirPath[i] = '\' then begin
SetLength(lpszExeDirPath,i);
break;
end;
end;
Result := lpszExeDirPath;
end;
function WindowProc(wnd:HWND; Msg : Integer; Wparam:Wparam; Lparam:Lparam):Lresult;stdcall;
var
KS : TKeyboardState;
TDC : HDC;
Begin
{Далее происходит цикл обработки сообщений}
case msg of
WM_CREATE:
begin
bmpUp := LoadImage(0, PChar(GetRootDir+'ups.bmp'),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
end;
WM_KEYDOWN:
begin
if wParam = VK_SHIFT
then begin
if (GetKeyState(VK_TAB)=1) then
mEssageBox(0,0,0,MB_OK);
end;
end;
WM_DRAWITEM:
begin
TDC := CreateCompatibleDC(0);
SelectObject(TDC, bmpUp);
SetBkMode(PDRAWITEMSTRUCT(Lparam)^.hDC, TRANSPARENT);
BitBlt(PDRAWITEMSTRUCT(Lparam)^.hDC,0,0,70,25,TDC, 0,0,SRCCOPY);
DeleteDC(TDC)
end;
WM_LBUTTONDOWN:
begin
Rectangle(GetWindowDC(wnd),80,80, 120,120);
end;
WM_DESTROY:
begin
DeleteObject(bmpUp);
PostQuitMessage(0);
Result:=0;
Exit;
end;
else Result:=DefWindowProc(wnd,msg,wparam,lparam);
end;
End;
{Переменные xPos,yPos,nWidth,nHeight в принципе не нужны, однако я их завел
(и вам рекомендую) для лучшей читабельности программы}
var
xPos,yPos,nWidth,nHeight : Integer;
begin //Тело программы
{ Далее идет заполнение шаблона класса окна}
wc.cbSize:=sizeof(wc);
wc.style:=cs_hredraw or cs_vredraw;
wc.lpfnWndProc:=@WindowProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=HInstance;
wc.hIcon:=LoadIcon(0,idi_application);
wc.hCursor:=LoadCursor(0,idc_arrow);
wc.hbrBackground:=COLOR_BTNFACE+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:='WinMin : Main';
RegisterClassEx(wc); //Регистрация нового класса в системе
{'заполнение переменных xPos,yPos,nWidth,nHeight}
xPos:=100;
yPos:=150;
nWidth:=400;
nHeight:=250;
{ Создание главного окна}
MainWnd:=CreateWindowEx (
0, //флаги расширенных стилей
'WinMin : Main', //имя класса окна, данное при заполнении структуры wc
'Win Min', //заголовок окна
ws_overlappedwindow, //флаги стилей окна
{подробнdее о стилях см. после текста программы}
xPos, //горизонтальная позиция окна
yPos, //вертикальная позиция окна
nWidth, //ширина окна
nHeight, //высота окна
0, //описатель родительского окна (parent) или окна-владельца (owner)
0, //описатель меню окна (меню нет, нет и описателя)
Hinstance, //описатель приложения
nil //address of window-creation data
);
Button1 := CreateWindow('BUTTON','_OK_', WS_CHILD or WS_VISIBLE or BS_OWNERDRAW, 10, 10, 70, 25, MainWnd, 0, HInstance, nil);
btnRgn := CreateEllipticRgn(10,10,30,25);
SetWindowRgn(Button1 , btnRgn, true);
ShowWindow(MainWnd,CmdShow); //Отображаем окно
While GetMessage(Mesg,0,0,0) do
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
end;
end.
Nick Denry (2005-09-09 16:46:00) [25]Мой код:
Button1 := CreateWindow('BUTTON','_OK_', WS_CHILD or WS_VISIBLE, 10, 10, 70, 25, MainWnd, 0, HInstance, nil);
btnRgn := CreateEllipticRgn(10,10,30,25);
SetWindowRgn(Button1 , btnRgn, true);
Да, я согласен - регион изменяется (т.е. нельзя мышкой ткнуть в какой либо угол кнопки, чтобы пришло WM_COMMAND), но ее внешний вид остается неизменным, и даже если она OWNERDRAW - то область осечения - не становится прозрачной - а выводится белым.
Игорь, я знаю что я туплю порой, неужели и в этот раз? :)
Игорь Шевченко (2005-09-09 16:29:00) [26]
> Народ подскажите , плиз, почему кнопка (обычный 'Button'
> class) не изменяет свою форму, если установить ей регион?
Изменяет