Собственно пытался сделать Subj, да ничего не вышло. Мой код для masm32 в аттачменте. Переписывал пример для TASM, взятый из исходников wasm.ru. С регионами раньше много пробовал в VB6, а вот что не так тут - я не понимаю. Да ведь и при компилировании, запуске, нет ошибок... И нет нужного результата. Может, WM_PAINT как-то надо по-другому? 93937023__rgn.zip
mc black в твоём примере регион создается после получения в оконной процедуре WM_CREATE. Попробуй вызвать CreateEllipticRgn и все остальные манипуляции с регионами непосредственно сразу после CreateWindowEx. Должно помочь.
Еееессс! Заработала Твой исходник я пока не смотрел, cresta. Очень убедительным был совет насчет делать это после CreateWindowEx! СПАСИБО!!! Ещё наблидается одна трабла: регион красиво рисуется, курсор принимает форму часиков, когда находится над окном. Если окно минимизировать, а потом показать, то трабла проходит. Что в этом случае может быть не так? В смысле я считаю, что часиков я видеть не должен. 396839516__rgn.zip
mc black Я в твоём исходнике хрен разберусь, какой-то старинный стиль написания кода У тебя вроде не обрабатывается никакое из сообщений, присылаемых при активации\деактивации окна. Если тебе надо, чтобы при деактивации твоего окна менялся курсор на старый, обрабатывай например сообщение WM_ACTIVATE, и смотри, что содержится в wParam, точнее в его low word. Там константа, соответствующая состоянию окна: Код (Text): mov eax,wParam and eax,0FFFFh cmp eax,WA_INACTIVE jne @ActivState ;тут что-нибудь делаем, если окно было деактивировано ;например восстанавливаем стандартный курсор jmp @Ret @ActivState: ;тут действия, если окно активировано ;например устанавливаем новый курсор @Ret: xor eax,eax ret P.S. Это в чем ты так программу пишешь?
Создавать регион по событию WM_CREATE можно. Для этого нужно обработать WM_NCCREATE и сохранить хендл переданный в оконную процедуру в качестве первого параметра в NEWHWND (значение возвращаемое CreateWindowEx сохранять смысла уже не будет). Подобный способ получения хэндла вообще предпочтителен.
cresta, этот стиль написания кода называется MASM 6.15 - ассемблер без макросредств (почти). Код с минимальными переделками можно откомпилить в TASM. Просто фрагменты кода я брал из книжки одного чукака (не запомнил фамилию..), который является сторонником "чистоты языка ассемблера". Это не hutch'евские макросы. А то получается, что немного макросов и ASM от VB6 уже не отличишь. Скриптовый язык получается, а не низкоуровневый Только какой это будет после всего ASM? invoke не используется - вместо этого параметры надо в обратном порядке в стэк ложить. Прототипы API объявляются в виде APIFunctionName@n:NEAR, где n - размер в байтах под параметры - смотрится так же, как в PEViewer'ах. В общем, вот... S_T_A_S, пытаюсь переварить тобой сказанное: > Для этого нужно обработать WM_NCCREATE и сохранить > хендл переданный в оконную процедуру в качестве > первого параметра в NEWHWND WNDPROC PROC ... CMP DWORD PTR [EBP+0CH], WMNCCREATE JE WMNCCREATE CMP DWORD PTR [EBP+0CH], WMCREATE JE WMCREATE ... WMNCCREATE: MOV [NEWHWND], DWORD PTR [EBP+08H] WMCREATE: PUSH 1 ;TRUE PUSH [hRgn] PUSH [NEWHWND] CALL SetWindowRgn@12 Правильно ли я тебя понял?
cresta > Хэндл окна получаешь сразу, как он становится валиден, и можно его использовать _до_ возвращения из CreateWindow. В случае проги mc black можно конечно оставить почти всё как есть: при WM_CREATE брать хэндл из параметров, а не из глобальной переменной (в которой ещё 0). Но когда создаётся несколько окошек на базе одного оконного класса, но нужны разные обработчики WM_CREATE, то проще эти хэндлы куда-нибудь сохранять по WM_NCCREATE. mc black Видимо стОит заменить на push DWORD PTR [EBP+08H] pop [NEWHWND] хотя в твоём случае проще убрать WMNCCREATE и делать push DWORD PTR [EBP+08H] вместо PUSH [NEWHWND] в WMCREATE
По поводу MOV [NEWHWND], DWORD PTR [EBP+08H] я уже сам догадался.. Что так не делают. Без WMNCCREATE - так действительно гораздо лучше смотрится Спасибо за помощь, S_T_A_S!!! Как мне "часики"-курсор сразу после создания убрать? cresta, неужели надо так напрямую делать с курсором, а можно сделать так, чтобы эта ситуация *до этого момента* не возникала? Такое чуство, что окно себя недорисованным считает. DeleteObject обязательно использовать, чтобы освобождать память от регионов или всё само освободится? Просто в примере cresta из RadASM и в примере для TASM там этого не делается. А в проектах на VB удалить объект - правило хорошего тона.. cresta, пишу в Aditor (там прикольная подсветка синтаксиса, типа как в RadASM), компилю не через RadASM, а ручками. Нормальный код, изучишь его - понятны будут и макросы.. надеюсь В общем можно смотреть венец моего творчества здесь:
Ну DeleteObject само собой Можно вызвать SetClassLong для своего класса окна с индексом GCL_HCURSOR, и указать курсор. Можно при регистрации указать wc.hCursor. Пока курсор в пределах окна, принадлежащего классу, курсор будет указанный тобой. При покидании пределов окна курсор сам сменится на дефолтный. О чистоте языка: дело вкуса. Как говорится, можно и в гамаке стоя О макросах: имхо достаточно знать что он из себя представляет и что вместо него будет скомпилировано. Необязательно ежесекундно доказывать себе, что ты полностью осознаешь каждый байт своего кода. В общем дело вкуса. Есть ведь люди, которые пишут в debug'e Или говорят что пишут.
cresta А ты, например, не поленился посмотреть, что будет вместо каждого используемого макроса? Мне бы лень было, скажу честно. А вообще, не буду спорить на эту тему - сам ещё не определился как буду писать. Я ведь в masm32 новичок. Насчет в гамаке стоя - прикольно А я так и делал. Код (Text): ;----------курсор окна PUSH IDC_ARROW PUSH 0 CALL LoadCursorA@8 MOV [WC.CLSHICON], EAX И всё равно... В WM_ACTIVATE повторно устанавливаю курсор - помогло, да это как-то неестественно.. В общем можно смотреть венец моего творчества здесь: _1213742057__rgn.zip
mc black > Это требование ОС - максимальное кол-во объектов GDI (общее для всех процессов) в 2K - 16384. Так что слишком много их не создашь. По завершению программы система сама всё должна освободить, но во всяких 9x это вроде бы плохо получается...
mc black А что ты раз за разом устанавливаешь один и тот же курсор IDC_ARROW ? К тому же и как для активного окна, так и для неактивного (wParam не проверяешь). Если хочешь чтобы для твоего окна был всегда один курсор, а для остальных приложений - другой, сделай проще: когда регистрируешь класс окна, укажи в качестве курсора например IDC_WAIT, и тебе не надо будет менять его постоянно. Если надо менять курсоры при активации\деактивации окна, то измени обработку WM_ACTIVATE так: Код (Text): WMACTIVATE: ;проверка low word wParam'a MOV EAX,DWORD PTR [EBP+10H] AND EAX,0FFFFH CMP EAX,WA_INACTIVE ;если окно неактивное JE DEFAULTCURSOR ;прыг на восстановление дефолтного курсора (стрелочка) PUSH IDC_HAND ;загружаем курсор, соответствующий активному состоянию PUSH 0 CALL LoadCursorA@8 PUSH EAX CALL SetCursor@4 ;устанавливаем "активный курсор" JMP FINISH DEFAULTCURSOR: PUSH IDC_ARROW ;загружаем курсор, соответствующий неактивному состоянию PUSH 0 CALL LoadCursorA@8 PUSH EAX CALL SetCursor@4 ;устанавливаем "неактивный курсор" JMP FINISH Код не проверял, но вроде должно работать. Кроме того, SetCursor возвращает предыдущий(заменяемый) курсор, можно его сохранить где-нибудь в глобальной переменной, и не дергать постоянно LoadCursor, просто подставлять из переменной. А макросы... Ну может с десяток использую, вряд ли больше. invoke,FUNC,SADD,local,m2m,.if-endif - даже эти несколько сильно экономят время и место.