Что нового

Скиновый модуль для приложения на AutoIt

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Решил попробовать написать скин для приложения, но получилось всё примитивно,
хотелось бы посмотреть что Вы думаете по этому поводу, что можно добавить или
как лучше сделать без создания GUI в модуле, модуль работает посредством
StdinWrite, на не аккуратность прошу не обращать внимания, я его только что
начал писать.

Ваше приложение

Код:
#include <WindowsConstants.au3>
#include <WinAPIEx.au3>

$hForm = GUICreate("", 300, 200, -1, -1, $WS_SIZEBOX)
SkinSetHWnd($hForm, @ScriptDir & "\skin.exe")
GUISetState()

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case -3
			Exit
	EndSwitch	
WEnd

Func SkinSetHWnd($hWnd, $hModule)
	$iPid = Run($hModule, "", @SW_HIDE, 1)
	StdinWrite($iPid, $hWnd)
EndFunc
Скиновый модуль

Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIEx.au3>

Global Const $SS_BITMAP = 0xE
Global Const $GWL_STYLE = -16

Global $sRead = ""

While 1
	$sRead &= ConsoleRead()
	If $sRead Then
		GUISetSkin($sRead)
	    $sRead = ""
	EndIf
WEnd

Func GUISetSkin($hWnd)
	$hWnd = HWnd($hWnd)
	$hPos = WinGetPos($hWnd)
	
	$Img1 = GUICreate("", $hPos[2], $hPos[3], $hPos[0], $hPos[1], BitOR($WS_POPUP, $WS_VISIBLE, $SS_BITMAP), $WS_EX_MDICHILD, $hWnd)
	$Bitmap1 = GUICtrlCreateIcon("", -1, 0, 0, $hPos[2], $hPos[3])
	GUICtrlSetState($Bitmap1, $GUI_DISABLE)
	GUICtrlSetImage($Bitmap1, @ScriptFullPath, 6000)
	GUISetState()
	
	_WinAPI_SetWindowLong($Img1, $GWL_STYLE, BitOR(_WinAPI_GetWindowLong($Img1, $GWL_STYLE), $WS_CLIPSIBLINGS, $WS_CLIPCHILDREN))
	
	While 1
	    If Not WinExists($hWnd) Then Exit	
		$sPos = WinGetPos($hWnd)
		WinMove($Img1, "", $sPos[0], $sPos[1]+20, $sPos[2], $sPos[3])
		GUICtrlSetPos($Bitmap1, 0, 0, $sPos[2], $sPos[3])
	Wend	
EndFunc

Для примера вот примитивный пример
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
219
Окно из модуля перекрывает содержимое основного окна.
А какой смысл в отдельном экзешнике?

Я, давно уже, видел скрипт, где весь вид окна, включая рамку и крестик справа сверху, изменялся с помощью GuiCtrlCreatePic.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Отдельный exe, это и будет отдельный скин который можно подключить к программе, на счет того что перекрывает, я не подумал :scratch:, но как тогда сделать? на Пурике я делал с помощью WinApi функции CreateWindowEx, а как здесь - не знаю.

Здесь нужно создать статический элемент на основном окне и отключить его, применяем графику и одеваем окно, но пока ни чего не приходит на ум
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Всё, зделал чтоб контролы не перекрывало, теперь встаёт вопрос с координатами, переместите главное окно в верхний левый угол монитора и всё увидите, окно из модуля не перемещается по тем же координатам что и главное.

skin.exe

Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIEx.au3>

Global Const $SS_BITMAP = 0xE
Global Const $GWL_STYLE = -16
Global $sRead = ""

While 1
	$sRead &= ConsoleRead()
	If $sRead Then
		WinSetSkin($sRead)
	    $sRead = ""
	EndIf
WEnd

Func WinSetSkin($hWnd)
	$hWnd = HWnd($hWnd)
	$hPos = WinGetPos($hWnd)
	
	$Img1 = GUICreate("", $hPos[2], $hPos[3], $hPos[0], $hPos[1], BitOR($WS_CHILD, $WS_VISIBLE, $SS_BITMAP, $WS_DISABLED), -1, $hWnd)
	$Bitmap1 = GUICtrlCreateIcon("", -1, 0, 0, $hPos[2], $hPos[3])
	GUICtrlSetState($Bitmap1, $GUI_DISABLE)
	GUICtrlSetImage($Bitmap1, @ScriptFullPath, 6000)
	GUISetState()
	
	_WinAPI_SetWindowLong($hWnd, $GWL_STYLE, BitOR(_WinAPI_GetWindowLong($hWnd, $GWL_STYLE), $WS_CLIPSIBLINGS, $WS_CLIPCHILDREN))

	While 1
	    If Not WinExists($hWnd) Then Exit	
		$sPos = WinGetPos($hWnd)
		WinMove($Img1, "", $sPos[0], $sPos[1]+20, $sPos[2], $sPos[3])
		GUICtrlSetPos($Bitmap1, 0, 0, $sPos[2], $sPos[3])
	Wend	

EndFunc

Координаты тоже зделал, только при стиле главного окна $WS_SIZEBOX, дочернее окно смещается, как вернуть стиль окна что бы скрипт понял что применено $WS_SIZEBOX и сместил координаты на правильные и не могу сделать прорисовку что бы при изменении размеров статический элемент не моргал.

Главный:

Код:
#include <WindowsConstants.au3>
#include <WinAPIEx.au3>

$hForm = GUICreate("", 300, 200, -1, -1, BitOR($WS_POPUP, $WS_SIZEBOX))
SkinSetHWnd($hForm, @ScriptDir & "\skin.exe")
GUICtrlCreateButton("",20, 20, 100, 20)
GUISetState()


While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case -3
			Exit
	EndSwitch	
WEnd

Func SkinSetHWnd($hWnd, $hModule)
	$iPid = Run($hModule, "", @SW_HIDE, 1)
	StdinWrite($iPid, $hWnd)
	Sleep(300)
EndFunc

Модуль:

Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIEx.au3>

Global Const $SS_BITMAP = 0xE
Global Const $GWL_STYLE = -16
Global $Img1
Global $sRead = ""

While 1
	$sRead &= ConsoleRead()
	If $sRead Then
		WinSetSkin($sRead)
	    $sRead = ""
	EndIf
WEnd

Func WinSetSkin($hWnd)
	$hWnd = HWnd($hWnd)
	$hPos = WinGetPos($hWnd)
	
	$Image1 = GUICreate("", $hPos[2], $hPos[3], $hPos[0], $hPos[1], BitOR($WS_CHILD, $WS_VISIBLE, $SS_BITMAP, $WS_DISABLED), -1, $hWnd)
	$Bitmap1 = GUICtrlCreateIcon("", -1, 0, 0, $hPos[2], $hPos[3])
	GUICtrlSetState($Bitmap1, $GUI_DISABLE)
	GUICtrlSetImage($Bitmap1, @ScriptFullPath, 6000)
	GUISetState()
	
	_WinAPI_SetWindowLong($hWnd, $GWL_STYLE, BitOR(_WinAPI_GetWindowLong($hWnd, $GWL_STYLE), $WS_CLIPSIBLINGS, $WS_CLIPCHILDREN))
    _WinAPI_SetWindowLong($Image1, $GWL_STYLE, BitOR(_WinAPI_GetWindowLong($Image1, $GWL_STYLE), $WS_CLIPSIBLINGS, $WS_CLIPCHILDREN))
	
	While 1
	    If Not WinExists($hWnd) Then ExitLoop	
		$hSize = WinGetPos($hWnd)
        $hClient = WinGetClientSize($hWnd)
        $hXPos = ($hSize[2] - $hClient[0]) / 2
        $hYPos = ($hSize[3] - $hClient[1]) - $hXPos
		
		WinMove($Image1, "", $hXPos, $hYPos, $hSize[2], $hSize[3])
		GUICtrlSetPos($Bitmap1, 0, 0, $hSize[2], $hSize[3])
	Wend	

EndFunc
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Попробывал на примере от Yashied'a, но ничего не получилось, хотел сделать через WinAPI

Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIEx.au3>

Global Const $SS_BITMAP         = 0xE
Global Const $GWL_STYLE         = -16
Global Const $STM_SETIMAGE      = 0x0172
Global Const $IMAGE_BITMAP      = 0
Global Const $LR_LOADFROMFILE   = 0x0010
Global Const $HWND_BOTTOM		= 1
Global Const $SWP_NOACTIVATE    = 0x0010
Global Const $SWP_NOZORDER	    = 0x0004

Global Const $IDC_ARROW = 32512
Global Const $WNDCLASSEX = "uint Size;uint Style;ptr hWndProc;int ClsExtra;int WndExtra;ptr hInstance;ptr hIcon;ptr hCursor;ptr hBackground;ptr MenuName;ptr ClassName;ptr hIconSm"
Global Const $sClass = "Static"
Global $hWnd_Static1
Global $SK_COMMAND = ""

While 1
	$SK_COMMAND &= ConsoleRead()
	If $SK_COMMAND Then 
	    WinSetSkin(HWnd($SK_COMMAND)) 
	EndIf	
WEnd

Func WinSetSkin($hWnd)
	
	$hPos = WinGetPos($hWnd)
	
    $tWndClassEx = DllStructCreate($WNDCLASSEX)
    $hWndProc = DllCallbackRegister('WindowCallback', 'lresult', 'hwnd;uint;wparam;lparam')
    $hInstance = _WinAPI_GetModuleHandle(0)
    $hCursor = _WinAPI_LoadCursor(0, $IDC_ARROW)
    $tIcon = DllStructCreate('ptr;ptr')
    _WinAPI_ExtractIconEx('shell32.dll', 130, DllStructGetPtr($tIcon, 1), DllStructGetPtr($tIcon, 2), 1)
    $hBrush = _WinAPI_CreateSolidBrush(_WinAPI_GetSysColor($COLOR_3DFACE))
	$tClass = DllStructCreate('wchar[' & StringLen($sClass) + 1 & ']')
    DllStructSetData($tClass, 1, $sClass)

    DllStructSetData($tWndClassEx, 'Size', DllStructGetSize($tWndClassEx))
    DllStructSetData($tWndClassEx, 'Style', 0)
    DllStructSetData($tWndClassEx, 'hWndProc', DllCallbackGetPtr($hWndProc))
    DllStructSetData($tWndClassEx, 'ClsExtra', 0)
    DllStructSetData($tWndClassEx, 'WndExtra', 0)
    DllStructSetData($tWndClassEx, 'hInstance', $hInstance)
    DllStructSetData($tWndClassEx, 'hIcon', DllStructGetData($tIcon, 1))
    DllStructSetData($tWndClassEx, 'hCursor', $hCursor)
    DllStructSetData($tWndClassEx, 'hBackground', $hBrush)
    DllStructSetData($tWndClassEx, 'MenuName', 0)
    DllStructSetData($tWndClassEx, 'ClassName', DllStructGetPtr($tClass))
    DllStructSetData($tWndClassEx, 'hIconSm', DllStructGetData($tIcon, 2))	
	
	DllCall('user32.dll', 'dword', 'RegisterClassExW', 'ptr', DllStructGetPtr($tWndClassEx))
	$hWnd_Static1 = DllCall('user32.dll', 'hwnd', 'CreateWindowExW', 'dword', 0, 'wstr', $sClass, 'str', "", 'dword', BitOR($WS_CHILD, $WS_VISIBLE, $SS_BITMAP, $WS_DISABLED), 'int', $hPos[0], 'int', $hPos[1], 'int', $hPos[2], 'int', $hPos[3], 'hwnd', $hWnd, 'hwnd', 0, 'hwnd', $hInstance, 'ptr', 0)
	
	$hBitmap1 = _WinAPI_LoadImage(0, @ScriptDir & "\bg.bmp", $IMAGE_BITMAP, 0, 0, $LR_LOADFROMFILE)
	DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hWnd_Static1, 'int', $STM_SETIMAGE, 'int', $IMAGE_BITMAP, 'dword', $hBitmap1)
	
	_WinAPI_SetWindowLong($hWnd, $GWL_STYLE, BitOR(_WinAPI_GetWindowLong($hWnd, $GWL_STYLE), $WS_CLIPSIBLINGS, $WS_CLIPCHILDREN))

	While 1
	    $SK_COMMAND &= ConsoleRead()
	    If $SK_COMMAND = "/E" Then Exit
		$SK_COMMAND = ""
	Wend

    DllCall('user32.dll', 'dword', 'UnregisterClassW', 'wstr', $sClass, 'ptr', $hInstance)
    DllCallbackFree($hWndProc)
EndFunc

Func WindowCallback($hWnd, $iMsg, $wParam, $lParam)
    Switch $iMsg
        Case $WM_CLOSE
            $Exit = 1
		Case $WM_SIZE
            $hSize = WinGetPos($hWnd)
		    $hClient = WinGetClientSize($hWnd)
		    $hXPos = ($hSize[2] - $hClient[0]) / 2
		    $hYPos = ($hSize[3] - $hClient[1]) - $hXPos
		    _WinAPI_SetWindowPos($hWnd_Static1, $HWND_BOTTOM, $hXPos, $hYPos, $hSize[2], $hSize[3], BitOR($SWP_NOACTIVATE, $SWP_NOZORDER)) 			
    EndSwitch
    Return _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam)
EndFunc

Что здесь не правильно?
 

Zaramot

I ♥ AutoIt
Сообщения
1,160
Репутация
660
+:
Уш лучше использовать Skincrafter, чем твой модуль (который не работает).
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
OffTopic:
Ну так используй, я его не для тебя делаю
 
Верх