|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 23, 2003 20:15:52 Значит так: надумал я создать компонентик - кнопка на основе GDI+. Я в этом деле начинающий так что буду рад совету от Знающих как мне сделать следующее... Надо чтобы кнопку можно было создать специальной функцией например CreateGdipButton proc hBrush, rect... Мне в этом не понятно только одно: кнопка - это окно значит его создают так: RegisterClassEx + CreateWindowEx. Там есть процедура WndProc, обрабатывающая события от винды. Дак вот при создании нескольких кнопок адрес этой процедуры никуда не денется т.е. у всех кнопок будет один и тот же обработчик событий? Или как? Или я чтото напутал? А может для каждой кнопки свой тред создавать? Или как? Подскажите а... |
|
|
Дата: Авг 23, 2003 22:57:40 Дак вот при создании нескольких кнопок адрес этой процедуры никуда не денется т.е. у всех кнопок будет один и тот же обработчик событий? Естественно. А может для каждой кнопки свой тред создавать? Нет. Лучше всего написать DLL. DllEntry - DLL_PROCESS_ATTACH: заполнить WNDCLASSEX и вызвать RegisterClassEx. Не забудьте добавить CS_GLOBALCLASS в WNDCLASSEX.style. Иначе контрол не будет создаваться в пользовательском процессе (вне DLL). DllEntry - DLL_PROCESS_DETACH: UnregisterClass Скелет на MASM32: .DATA
szClassName db 'GdipButton',0
.DATA?
hInst dd ?
.CODE
DllEntry PROC hInstance:DWORD,reason:DWORD,resvd:DWORD
LOCAL wc:WNDCLASSEX
.IF reason == DLL_PROCESS_ATTACH
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_GLOBALCLASS
mov wc.lpfnWndProc,OFFSET GdipButton
mov eax,hInstance
mov hInst,eax
mov wc.hInstance,eax
mov wc.lpszClassName,OFFSET szClassName
xor eax,eax
mov wc.hbrBackground,eax
mov wc.cbClsExtra,eax
mov wc.cbWndExtra,eax
mov wc.hIcon,eax
mov wc.hIconSm,eax
mov wc.lpszMenuName,eax
invoke LoadCursor,eax,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx,ADDR wc
.ELSEIF reason == DLL_PROCESS_DETACH
invoke UnregisterClass,OFFSET szClassName,hInst
.ENDIF
mov eax,1
ret
DllEntry ENDP
; Button callback (WndProc)
GdipButton PROC hWnd:DWORD,uMsg:DWORD,wP:DWORD,lP:DWORD
mov eax,uMsg
.IF eax == WM_PAINT
; Рисуем кнопку
; . . .
.ELSEIF eax == WM_CREATE
; . . .
.ELSEIF eax == WM_DESTROY
; . . .
.ELSE
invoke DefWindowProc,hWnd,uMsg,wP,lP
.ENDIF
ret
GdipButton ENDP
; DLL должна экспортировать хоть одну ф-цию
; Иначе её не прилинкуешь статически
myStub PROC
ret
myStub ENDP
END DllEntry |
|
|
Дата: Авг 24, 2003 07:26:05 Понял, спасибо! Я так уже делал, но вдруг както подругому можно. Но тут другая проблема вылезает - в MSDN написано, что в GDI+ нельзя вызывать функцию GdiplusStartup, я так и не понял почему. Я пытался рисовать GDI+ом при помоши сабклассинга - хотел перехватить WM_ERASEBKGND, сообщение перехватил, а GDI+ не рисует. Мне кажется это связано, ведь все контролы находятся в DLL. |
|
|
Дата: Авг 24, 2003 18:40:23 Ну сделал я эту штуку DLL-кой и получилось, что для разных кнопок вызывается один и тот же код и используются одни и те же данные. Т.е. вызов вот этого: invoke CreateGdipButton,ADDR TestString1, hWnd, ADDR rectBut1 invoke CreateGdipButton,ADDR TestString2, hWnd, ADDR rectBut2 дает два абсолютно одинаковых окошка с текстом из TestString2. Ну короче как я и говорил. Текст процедуры такой: CreateGdipButton proc pText:DWORD, hWnd:DWORD, pRect:DWORD LOCAL wc:WNDCLASSEX invoke GetModuleHandle, NULL mov hInstance,eax mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style,CS_HREDRAW+CS_VREDRAW+CS_DBLCLKS mov wc.lpfnWndProc,OFFSET ButtonWndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInstance pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ButtonClassName mov wc.hIcon,NULL mov wc.hIconSm,NULL invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc mov edi,pRect invoke CreateWindowEx,WS_EX_CLIENTEDGE,addr ButtonClassName,0,\ WS_CHILD or WS_VISIBLE,(RECT ptr [edi]).left,(RECT ptr [edi]).top,\ (RECT ptr [edi]).right, (RECT ptr [edi]).bottom,\ hWnd,0,hInstance,0 m2m pButtonText,pText ; mov hwndTextEdit,eax ret CreateGdipButton endp |
|
|
Дата: Авг 24, 2003 18:53:14 profi_r дает два абсолютно одинаковых окошка с текстом из TestString2 Так и должно быть, ведь переменная pButtonText одна на всю DLL :-) Текст нужно сохранять по отдельности для каждой кнопки. Хороший кандидат на роль буфера для этого текста -- это параметр lpWindowName ф-ции CreateWindowEx (у вас там ноль). Например:
invoke CreateWindowEx,WS_EX_CLIENTEDGE,\
addr ButtonClassName,pText,\
WS_CHILD or WS_VISIBLE,\
(RECT ptr [edi]).left,(RECT ptr [edi]).top,\
(RECT ptr [edi]).right,(RECT ptr [edi]).bottom,\
hWnd,0,hInstance,0
; Потом в обработчике сообщений
; (на WM_PAINT, например):
invoke SendMessage,hButton,WM_GETTEXT,64,OFFSET strBuf
; Рисуем этот текст на кнопке |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.107 |