Прозрачный фон окна - Assembler
Формулировка задачи:
Приветствую! Создал окно с прозрачным фоном (WS_EX_LAYERED +WS_POPUP+ SetLayeredWindowAttributes,eax,0,200,LWA_ALPHA) и все получилось, но вот проблема: при навешивании кнопок, едитов и т.п. они наследуют прозрачность. Как убрать наследственность ?
Решение задачи: «Прозрачный фон окна»
textual
Листинг программы
format PE GUI 4.0 entry start include 'win32a.inc' include 'macro\if.inc' HTCAPTION = 2 section '.data' data readable writeable _class db 'WIN1',0 _title db 'Основное Окно',0 _error db 'Ошибка основного окна',0 _cstatic db 'STATIC',0 _tmin db 'MIN:',0 _classb db 'BUTTON',0 _textb db 'КНОПКА',0 hBitmap dd ? ;дескриптор фонового изображения hdc dd ? ;дескриптор холста hMemDC dd ? ;дескриптор копии холста my dd ? wc WNDCLASS 0,WindowProc,0,0,0,0,0,COLOR_BTNFACE+1,0,_class msg MSG ps PAINTSTRUCT rect RECT ;: section '.code' code readable executable start: invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadIcon,0,IDI_APPLICATION mov [wc.hIcon],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc cmp eax,0 je error invoke CreateWindowEx,WS_EX_LAYERED,_class,_title,WS_VISIBLE+WS_POPUP+WS_BORDER\ ,128,128,900,700,0,0,[wc.hInstance],0 cmp eax,0 je error mov [wc.hIcon],eax invoke SetLayeredWindowAttributes,eax,0,200,LWA_ALPHA mtk_msg_loop: invoke GetMessage,msg,0,0,0 cmp eax,0 je mtk_end_loop invoke TranslateMessage,msg invoke DispatchMessage,msg jmp mtk_msg_loop error: invoke MessageBox,0,_error,0,MB_ICONERROR+MB_OK mtk_end_loop: invoke ExitProcess,[msg.wParam] proc WindowProc hwnd,wmsg,wparam,lparam push ebx esi edi cmp [wmsg],WM_CREATE je .wmcreate cmp [wmsg],WM_LBUTTONDOWN je .wmlbuttondown cmp [wmsg],WM_DESTROY je .wmdestroy cmp [wmsg],WM_PAINT je .wmpaint .defwndproc: ;:: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .finish ;: .wmcreate: ;:: invoke CreateWindowEx,0,_cstatic,_tmin,WS_VISIBLE+WS_CHILD, 60,120,40,20,[hwnd],0,[wc.hInstance],NULL invoke CreateWindowEx,0,_classb,_textb,WS_VISIBLE+WS_CHILD+BS_PUSHBUTTON, 60,60,100,50,[hwnd],1001,[wc.hInstance],NULL invoke SetLayeredWindowAttributes,eax,0,0,LWA_ALPHA invoke LoadBitmap,[wc.hInstance],1 mov [hBitmap],eax invoke GetWindowDC,[hwnd] mov [hdc],eax invoke CreateCompatibleDC,[hdc] mov [hMemDC],eax invoke SelectObject,[hMemDC],[hBitmap] ; вызов процедуры создания региона invoke GetClientRect,[hwnd],rect push [rect.bottom] push [rect.right] push [hMemDC] call MakeRegion ; применить регион к окну invoke SetWindowRgn,[hwnd],eax,TRUE invoke ReleaseDC,[hwnd],[hdc] invoke DeleteDC,[hMemDC] jmp .finish ;: .wmpaint: ;:: invoke BeginPaint,[hwnd],ps mov [hdc],eax invoke CreateCompatibleDC,[hdc] mov [hMemDC],eax invoke SelectObject,[hMemDC],[hBitmap] invoke GetClientRect,[hwnd],rect invoke BitBlt,[hdc],0,0,[rect.right],[rect.bottom],[hMemDC],0,0,SRCCOPY invoke DeleteDC,[hMemDC] invoke EndPaint,[hwnd],ps jmp .finish ;: .wmlbuttondown: ;:: invoke ReleaseCapture invoke SendMessage,[hwnd],WM_NCLBUTTONDOWN,HTCAPTION,0 jmp .finish ;: .wmdestroy: ;:: invoke PostQuitMessage,0 mov eax,0 ;: .finish: ;:: pop edi esi ebx ret ;: endp proc MakeRegion var_hDC,var_PicWidth,var_PicHeight local var_X:DWORD ; столбец local var_Y:DWORD ; ряд local var_StartLineX:DWORD ; левый край текущего региона local var_FullRegion:DWORD ; комплексный регион local var_LineRegion:DWORD ; текущий регион local var_TransparantColor:DWORD ; прозрачный цвет (исключается из региона) local var_InFirstRegion:DWORD ; первый регион (Да/Нет) local var_Inline:DWORD ; создается линия региона (Да/Нет) mov [var_InFirstRegion],TRUE mov [var_Inline],FALSE mov [var_X],0 mov [var_Y],0 mov [var_StartLineX],0 invoke GetPixel,[var_hDC],0,0 ; получаем прозрачный цвет из левого верхнего пикселя картинки mov [var_TransparantColor],eax mov ebx, [var_PicHeight] .while [var_Y] < ebx ; повторяем до нижнего ряда mov ebx,[var_PicWidth] .while [var_X] <= ebx ; повторяем до правого столбца в каждом ряду invoke GetPixel,[var_hDC],[var_X],[var_Y] ; получаем текущий пиксель mov ebx,[var_PicWidth] ; проверяем, является ли пиксель прозрачным или достигнут конец ряда .if eax=[var_TransparantColor] | [var_X]=ebx ; если это так, то проверим еще, имеется ли у нас линия, которую надо добавить в регион ; или это лишь очередной прозрачный пиксель, и мы должны просто двигаться дальше .if [var_Inline]=TRUE mov [var_Inline],FALSE mov ebx,[var_Y] inc ebx invoke CreateRectRgn,[var_StartLineX],[var_Y],[var_X],ebx mov [var_LineRegion],eax .if [var_InFirstRegion]=TRUE ; если это первый созданный регион, то мы просто ; сохраним его дескриптор в комплексный регион push [var_LineRegion] pop [var_FullRegion] mov [var_InFirstRegion],FALSE .else ; иначе — добавим полученный регион к комплексному региону ; а затем удалим текущий для освобождения памяти invoke CombineRgn,[var_FullRegion],[var_FullRegion],[var_LineRegion],RGN_OR invoke DeleteObject,[var_LineRegion] .endif .endif .else .if [var_Inline]=FALSE ; текущий пиксель не прозрачный, это не конец ряда, и мы не на этапе создания линии ; значит, этот пиксель будем считать первым пикселем очередной линии mov [var_Inline],TRUE push [var_X] pop [var_StartLineX] .endif .endif inc [var_X] mov ebx,[var_PicWidth] .endw inc [var_Y] mov [var_X],0 mov ebx,[var_PicHeight] .endw mov eax,[var_FullRegion] ; возвращаем готовый регион в точку вызова процедуры ret endp ;: section '.idata' import data readable writeable library gdi32,'GDI32.DLL',\ kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include 'api\gdi32.inc' include 'api\kernel32.inc' include 'api\user32.inc' ;: section '.rsrc' resource data readable directory RT_BITMAP,bitmaps;,RT_DIALOG,dialogs,RT_ICON,icons,RT_GROUP_ICON,group_icons,RT_VERSION,versions ;resource icons,1,LANG_NEUTRAL,icon_data ;resource group_icons,17,LANG_NEUTRAL,main_icon resource bitmaps,1,LANG_NEUTRAL,pict ;resource versions,2,LANG_ENGLISH+SUBLANG_DEFAULT,version ;resource dialogs,37,LANG_ENGLISH+SUBLANG_DEFAULT,main bitmap pict,'fon.bmp' ;icon main_icon,icon_data,'bmp.ico' ;dialog main,'Картинка в диалоге',10,10,213,147,WS_VISIBLE+WS_POPUP+\ ;WS_CAPTION+WS_SYSMENU+DS_CENTER+DS_MODALFRAME ;dialogitem 'STATIC',IDR_PICT,-1,0,0,0,0,WS_VISIBLE+SS_BITMAP ;dialogitem 'BUTTON','&OK',IDOK,50,130,45,15,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON ;dialogitem 'BUTTON','&Cancel',IDCANCEL,120,130,45,15,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON ;enddialog ;versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\ ;'FileDescription','Bitmap example',\ ;'LegalCopyright',<'Copyright ',0A9h,' BarMentaLisk 2008'>,\ ;'FileVersion','0.1',\ ;'ProductVersion','0.1',\ ;'OriginalFilename','bmp_example' ;: