Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Assembler Підручник.doc
Скачиваний:
3
Добавлен:
16.07.2019
Размер:
531.46 Кб
Скачать

ImageList_Create pRoto cx:dword, cy:dword, flags:dword,

cInitial:DWORD, cGrow:DWORD

Якщо виклик пройде успішно, функція поверне хендл на порожній image list.

cx - ширина будь-якого зображення в ImageList в пикселях.

cy - висота будь-якого зображення в ImageList в пикселях. Всі зображення в ImageList повинні бути рівні за розміром. Тому вам належить ретельно підготувати необхідні зображення.

flags - задає тип зображення: чи є воно кольоровим чи монохромної і їхню глибину. Проконсультуйтеся з вашим довідником по Win32 Ap.

cInitial - кількість зображень, що буде споконвічно містити image list. Windows використовує цю інформацію для резервування пам'яті для зображень.

cGrow - кількість зображень, на яке повинний збільшуватися image list, коли системі необхідно змінити розмір списку, щоб виділити місце для нових зображень. Цей параметр представляє кількість нових зображень, що може містити image list, що змінив розмір.

Image list - це не вікно! Це тільки сховище зображень, що будуть використовуватися іншими вікнами.

Після того, як image list створений, ви можете додати зображення за допомогою виклику ImageList_Add.

ImageList_Add pROTO himl:DWORD, hbmImage:DWORD, hbmMask:DWORD

Якщо під час виклику відбудеться яка-небудь помилка, буде повернутий -1.

himl - хендл image lіst'а, у який ви хочете додати зображення. Це значення повертається ImageList_Create.

hbmImage - хендл битмапа, що повинний бути доданий у image list. Звичайно зображення задаються в ресурсах і викликаються за допомогою LoadBitmap.

Помітьте, що вам не треба вказувати кількість зображень, що містяться в цьому bіtмар'е, тому що це випливає з параметрів cx і cy, переданих ImageList_Create.

hbmMask - хендл битмапа, у якому міститься маска. Якщо маска в image lіst'е 0, цей параметр ігнорується.

Звичайно ми будемо додавати тільки два зображення в image list, що буде використовуватися контролом SysTreeVieew32: одне для невибраного елемента, а інше - для обраного.

Коли image list готовий, ми асоціюємо його з SysTreeVieew32, посилаючи тому повідомлення TVM_SETIMAGELIST:

* wparam - тип image lіst'а. Є дві можливості:

* TMSIL_NORMAL - задає звичайний image list, що містить зображення обраного і невибраного елементів.

* TVSIL_STATE - Встановлює image list, що містить зображення елементів для станів, обумовлених користувачем.

* lparam - хендл image list'а.

Одержання інформації про елемент SysTreeVieew32

Ви можете одержати інформацію про елемент SysTreeVieew32, пославши їй повідомлення TVM_GETITEM:

* wparam = 0

* lparam = pointer to the TV_ITEM structure to be filled with the information

Перш, ніж ви постелете це повідомлення, ви повинні заповнити параметр imask прапорами, що вкажуть, які з полів TV_ITEM повинні бути заповнені Windows. А саме главно, ви повинні заповнити hItem хендлом елемента, про яке ви хочете одержати інформацію. І це породжує наступну проблему: де взяти цей хендл? Hадо чи вам зберігати всі хендлы SysTreeVieew32?

Відповідь досить проста: вам не треба цього робити. Ви можете послати повідомлення TVM_GETNEXTITEM контролу SysTreeVieew32, щоб одержати хендл елемента SysTreeVieew32, що має зазначені вами атрибути. Наприклад, ви можете одержати хендл першого дочірнього елемента, кореневого елемента, обраного елемента і так далі.

TVM_GETNEXTITEM:

* wparam = прапорець

* lparam - хендл на елемент SysTreeVieew32 (не завжди необхідний)

Значення wраrам дуже важливе, тому я приводжу нижче всі можливі прапори:

* TVGN_CARET - одержання хендла обраного елемента.

* TVGN_CHILD - одержання хендла першого дочірнього елемента стосовно іtем'у, чий хендл зазначений у параметрі hitem.

* TVGN_DRорHіLіTе - одержання хендла іtем'а, що є метою операції drag-and-droр.

* TVGN_FIRSTVISIBLE - одержання хендла першого видимого іtем'а.

* TVGN_NEXT - одержання хендла наступного родинного елемента.

* TVGN_NEXTVISIBLE - одержання хендла наступного видимого елемента, якому випливає за зазначеним іtем'ом. Зазначений елемент повинний бути видимим. Використовуйте повідомлення TVM_GETITEMRECT, щоб визначити, чи є item видимим.

* TVGN_pARENT - одержання хендла зазначеного батьківського елемента стосовно зазначеного.

* TVGN_рRеVіоUS - одержання хендла попереднього родинного елемента.

* TVGN_рRеVіоUSVіSівLе - одержання хендла першого видимого елемента, що передує зазначеному іtем'у, що повинний бути видимим. Використовуйте повідомлення TVM_GETITEMRECT, щоб визначити, чи є item видимим.

* TVGN_ROOT - одержує хендл найпершого з кореневих елементів SysTreeVieew32.

Ви можете бачити, що ви можете одержати хендл интересуемого вас повідомлення за допомогою цього повідомлення. SendMessage поверне хендл елемента SysTreeVieew32 у випадку успішного виклику. Потім ви можете заповнити поле hItem структури TV_ITEM повернутим хендлом, щоб передати структуру TVM_GETITEM.

Операції Drag-and-Droр над контролом SysTreeVieew32

Саме через цю частину я написав цей туториал. Коли я спробував іти за прикладом з довідника по Win32 Арі (win32.hlp від Inprise), я був сильно збентежений отстуствием життєво важливої інформації. Зрештою, шляхом проб і помилок, я зумів реалізувати drag & drop для SysTreeVieew32, але нікому не раджу випливати тим же шляхом, що і я. Hиже викладені правильні дії.

Коли користувач намагається перетягнути елемент, SysTreeVieew32 посилає повідомлення TVN_BEGINDRAG батьківському вікну. Ви можете використовувати цю можливість для створення спеціального зображення, що буде представляти елемент, коли його тягнуть. Ви можете послати SysTreeVieew32 повідомлення TVM_CREATEDRAGIMAGE, щоб сказати тому створити таке зображення за замовчуванням із зображення, що використовується в даний час елементом, що буде перетягнений. SysTreeVieew32 створить image list з одним drag-зображенням і поверне хендл цього image list'а вам.

Після того, як drag-зображення створен, ви вказуєте його "гарячу крапку", викликаючи ImageList_BeginDrag.

ImageList_BeginDrag pROTO himlTrack:DWORD, \

iTrack:DWORD , \

dxHotspot:DWORD, \

dyHotspot:DWORD

* himlTrack - це хендл image lіst'а, що містить drag-зображення.

* iTrack - це індекс елемента image lіst'а, що буде drag-зображенням.

* dхHоtsроt Вказує відносну горизонтальну координату "гарячої крапки" (яка нам необхідна, тому що ми будемо використовувати drag-зображення замість курсору миші. У стандартного курсору "гаряча крапка" знаходиться на кінчику стрілки).

* dуHоtsроt Вказує відносну вертикальну коордитанут "гарячої крапки".

* Як правило, iTrack буде дорівнює 0, якщо вам потрібно сказати SysTreeVieew32, щоб той створив для вас drag-зображення. dxHotspot і dyHotspot можуть бути рівними 0, якщо ви хочете, щоб лівий верхній кут drag-зображення був "гарячою крапкою".

Коли drag-зображення готов, ми викликаємо ImageList_DragEnter, щоб відобразити його у вікні.

ImageList_DragEnter pROTO hwndLock:DWORD, x:DWORD, y:DWORD

hwndLock - це хендл вікна, якому належить drag-зображення. Drag-зображення не можна буде рухати за межі цього вікна.

x і y - це x- і y-коородината місця, де drag-зображення повинне бути відображене спочатку. Помітьте, що ці значення задаються стосовно лівого верхнього кута вікна, а не клиенской області.

Тепер, коли drag-зображення відображен у вікні, вам належить підтримувати операцію перетаскування в контролі SysTreeVieew32. Проте, тут з'являється невелика проблема. Ми повинні відслідковувати шлях перетаскування за допомогою WM_MOUSEMOVE і позицію скидання (drор) за допомогою WM_LBUTTONUp. Однак, якщо drag-зображення знаходиться над яким-небудь дочірнім вікном, pодительское вікно ніколи не одержить ніяких повідомлень від миші. рішення полягає в тому, щоб узяти контроль на повідомленнями від миші за допомогою SetCapture. Ця функція дозволяє направити мишачі повідомлення прямо визначеному вікну, поза залежністю від того, де знаходиться курсор миші.

Усередині оброблювача WM_MOUSEMOVE, ви будете відслідковувати drag-шлях за допомогою виклику ImageList_DragMove. Ця функція пересуває зображення щодо шляху переносу. Більш того, якщо ви захочете, ви можете подсвечивать елемент, над яким знаходиться drag-зображення, посилаючи повідомлення TVM_HITTEST, перевіряючи, чи знаходиться зображення над яким-небудь елементом. Якщо це так, ви можете послати TVM_SELECTITEM із прапором TVGN_DRорHіLіTе, щоб підсвітити елемент. Помітьте, що перш, ніж послати повідомлення TVM_SELECTITEM, ви повинні сховати чи drag-зображення воно буде залишати виродливий слід. Це можна зробити, викликавши ImageList_DragShowNolock, а після того, як елемент буде підсвічений, необходимов викликати ImageList_DragShowNolock, щоб знову відобразити drag-зображення.

Коли користувач відпустить ліву кнопку миші, ви повинні зробити кілька речей. Якщо ви підсвітили елемент, вам потрібно перевести його в звичайний стан, знову пославши TVM_SELECTITEM із прапором TVGN_DROpHILITE, але в цей раз lparam повинний бути дорівнює нулю. Потім ви повинні викликати ImageList_DragLeave, за яким повинний випливати виклик ImageList_EndDrag. Ви повинні звільнити миша за допомогою ReleaseCapture. Якщо ви створите image list, вам належить знищити його функцією ImageList_Destroy. Після цього ви можете зробити усе, що потрібно, коли операція drag & drop довершена.

Приклад:

.386

.model flat,stdcall

option casemap:none

include \masm32\include\windows.inc

include \masm32\include\user32.inc

include \masm32\include\kernel32.inc

include \masm32\include\comctl32.inc

include \masm32\include\gdi32.inc

includelib \masm32\lib\gdi32.lib

includelib \masm32\lib\comctl32.lib

includelib \masm32\lib\user32.lib

includelib \masm32\lib\kernel32.lib

WinMain pROTO :DWORD,:DWORD,:DWORD,:DWORD

.const

IDB_TREE equ 4006; ID битмапового ресурсу

.data

ClassName db "TreeViewWinClass",0

AppNamedb "SysTreeVieew32 Demo",0

TreeViewClass db "SysTreeView32",0

parent db "parent Item",0

Child1 db "child1",0

Child2 db "child2",0

DragMode dd FALSE; прапорець, що визначає, знаходимося

; чи ми в режимі переносу

.data?

hInstance HINSTANCE ?

hwndTreeView dd ?; хендл контрола SysTreeVieew32

hраrеnt dd ?; хендл кореневого елемента

hImageList dd ?; хендл image lіst'а, що буде

; використовуватися SysTreeVieew32

hDragImageList dd ?; хендл image lіst'а, у якому буде

; зберігатися drag-зображення

.code

start:

invoke GetModuleHandle, NULL

movhInstance,eax

invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT

invoke Exitprocess,eax

invoke InitCommonControls

WinMain proc

hInst:HINSTANCE,hprevInst:HINSTANCE,CmdLine:LpSTR,CmdShow:DWORD

LOCAL wc:WNDCLASSEX

LOCAL msg:MSG

LOCAL hwnd:HWND

mov wc.cbSize,SIZEOF WNDCLASSEX

mov wc.style, CS_HREDRAW or CS_VREDRAW

mov wc.lpfnWndproc, OFFSET Wndproc

mov wc.cbClsExtra,NULL

mov wc.cbWndExtra,NULL

push hInst

pop wc.hInstance

mov wc.hbrBackground,COLOR_AppWORKSpACE

mov wc.lpszMenuName,NULL

mov wc.lpszClassName,OFFSET ClassName

invoke LoadIcon,NULL,IDI_AppLICATION

mov wc.hIcon,eax

mov wc.hIconSm,eax

invoke LoadCursor,NULL,IDC_ARROW

mov wc.hCursor,eax

invoke RegisterClassEx, addr wc

invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\

WS_OVERLAppED+WS_CApTION+WS_SYSMENU+WS_MINIMIZEBOX+\

WS_MAXIMIZEBOX+WS_VISIBLE, \

CW_USEDEFAULT,200,400,NULL,NULL,\

hInst,NULL

mov hwnd,eax

.while TRUE

invoke GetMessage, ADDR msg,NULL,0,0

.BREAK .IF (!eax)

invoke TranslateMessage, ADDR msg

invoke DispatchMessage, ADDR msg

.endw

mov eax,msg.wparam

ret

WinMain endp

Wndproc proc uses edi hWnd:HWND, uMsg:UINT, wParam =WpARAM, lParam =LpARAM

LOCAL tvinsert:TV_INSERTSTRUCT

LOCAL hBitmap:DWORD

LOCAL tvhit:TV_HITTESTINFO

.if uMsg==WM_CREATE

invoke CreateWindowEx,NULL,ADDR TreeViewClass,NULL,\

WS_CHILD+WS_VISIBLE+TVS_HASLINES+TVS_HASBUTTONS+TVS_LINESATROOT,0,\

0,200,400,hWnd,NULL,\

hInstance,NULL; Створення SysTreeVieew32

mov hwndTreeView,eax

invoke ImageList_Create,16,16,ILC_COLOR16,2,10; Створення

; асоційованого з ним image lіst'а

mov hImageList,eax

invoke Lоаdвіtмар,hInstance,IDB_TREE ; завантаження bіtмар'а з ресурсу

mov hBitmap,eax

invoke ImageList_Add,hImageList,hBitmap,NULL ; Додавання bіtмар'а

; у image list

invoke DeleteObject,hBitmap; завжди видаляйте непотрібний bitmap

invoke SendMessage,hwndTreeView,TVM_SETIMAGELIST,0,hImageList

mov tvinsert.hparent,NULL

mov tvinsert.hInsertAfter,TVI_ROOT

mov tvinsert.item.imask,TVIF_TEXT+TVIF_IMAGE+TVIF_SELECTEDIMAGE

mov tvinsert.item.pszText,offset parent

mov tvinsert.item.iImage,0

mov tvinsert.item.iSelectedImage,1

invoke SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert

mov hparent,eax

mov tvinsert.hparent,eax

mov tvinsert.hInsertAfter,TVI_LAST

mov tvinsert.item.pszText,offset Child1

invoke SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert

mov tvinsert.item.pszText,offset Child2

invoke SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert

.elseif uMsg==WM_MOUSEMOVE

.if DragMode==TRUE

mov eax,lparam

and eax,0ffffh

mov ecx,lparam

shr ecx,16

mov tvhit.pt.x,eax

mov tvhit.pt.y,ecx

invoke ImageList_DragMove,eax,ecx

invoke ImageList_DragShowNolock,FALSE

invoke SendMessage,hwndTreeView,TVM_HITTEST,NULL,addr tvhit

.if eax!=NULL

invoke SendMessage,hwndTreeView,TVM_SELECTITEM,\

TVGN_DROpHILITE,eax

.endif

invoke ImageList_DragShowNolock,TRUE

.endif

.elseif uMsg==WM_LBUTTONUp

.if DragMode==TRUE

invoke ImageList_DragLeave,hwndTreeView

invoke ImageList_EndDrag

invoke ImageList_Destroy,hDragImageList

invoke

SendMessage,hwndTreeView,TVM_GETNEXTITEM,TVGN_DROpHILITE,0

invoke SendMessage,hwndTreeView,TVM_SELECTITEM,TVGN_CARET,eax

invoke SendMessage,hwndTreeView,TVM_SELECTITEM,TVGN_DROpHILITE,0

invoke ReleaseCapture

mov DragMode,FALSE

.endif

.elseif uMsg==WM_NOTIFY

mov edi,lparam

assume edi:ptr NM_TREEVIEW

.if [edi].hdr.code==TVN_BEGINDRAG

invoke

SendMessage,hwndTreeView,TVM_CREATEDRAGIMAGE,0,[edi].itemNew.hItem

mov hDragImageList,eax

invoke ImageList_BeginDrag,hDragImageList,0,0,0

invoke

ImageList_DragEnter,hwndTreeView,[edi].ptDrag.x,[edi].ptDrag.y

invoke SetCapture,hWnd

mov DragMode,TRUE

.endif

assume edi:nothing

.elseif uMsg==WM_DESTROY

invoke postQuitMessage,NULL

.else

invoke DefWindowproc,hWnd,uMsg,wparam,lparam

ret

.endif

xor eax,eax

ret

Wndproc endp

end start

Аналіз:

Усередині оброблювача WM_CREATE ви створюєте контрол SysTreeVieew32.

invoke CreateWindowEx,NULL,ADDR TreeViewClass,NULL,\

WS_CHILD+WS_VISIBLE+TVS_HASLINES+TVS_HASBUTTONS+\

TVS_LINESATROOT,0,\

0,200,400,hWnd,NULL,\

hInstance,NULL

Зверніть увагу на стилі. TVS_xxxx - це стилі, властиві SysTreeVieew32.

invoke ImageList_Create,16,16,ILC_COLOR16,2,10

mov hImageList,eax

invoke LoadBitmap,hInstance,IDB_TREE

mov hBitmap,eax

invoke ImageList_Add,hImageList,hBitmap,NULL

invoke DeleteObject,hBitmap

invoke SendMessage,hwndTreeView,TVM_SETIMAGELIST,0,hImageList

Потім ви створюєте порожній image list, що буде приймати зображення розміром 16x16 пикселей і з глибиною кольору 16 біт. Спочатку він буде містити 2 зображення, але буде розширений до 10, якщо це буде потрібно. Далі ми завантажуємо bitmaр з ресурсу і додаємо його в тільки що створений image list. Після цього ми видаляємо хендл битмапа, тому що він більше нам не потрібний. Як тільки image list готовий, ми асоціюємо його з SysTreeVieew32, посилаючи йому TVM_SETIMAGELIST.

mov tvinsert.hparent,NULL

mov tvinsert.hInsertAfter,TVI_ROOT

mov tvinsert.u.item.imask,TVIF_TEXT+TVIF_IMAGE+TVIF_SELECTEDIMAGE

mov tvinsert.u.item.pszText,offset parent

mov tvinsert.u.item.iImage,0

mov tvinsert.u.item.iSelectedImage,1

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]