Разработчик
Регистрация: 08.08.2011
Сообщений: 505
Написано 191 полезных сообщений (для 369 пользователей)
|
Для тех, кому в блице внезапно не хватило браузера, word и тд
В общем, для любителей извращений с блицем, если вам внезапно в окне блица понадобился браузер, Word, блокнот, косынка и пасьянс
Код AutoIt 3.3.14.2:
#NoTrayIcon
#include <WinAPI.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>
#Include <Word.au3>
Opt("WinTitleMatchMode", 3)
$eXn = @ScriptDir & '\bin.exe'
$lPn = 'SCL.auto'
$aRet = _GetDesktopWorkArea()
If Not WinExists($lPn) Then
if _WinAPI_GetVersion() = 10 then
$dw = _WinAPI_GetSystemMetrics(16) - 2 * _WinAPI_GetSystemMetrics(6)
$dh = _WinAPI_GetSystemMetrics(17) - _WinAPI_GetSystemMetrics(6) - _WinAPI_GetSystemMetrics(7)
ShellExecute ($eXn, string($dw) & "/" & string($dh))
WinMove (WinWaitactive($lPn), "", $aRet[0] - 2 * _WinAPI_GetSystemMetrics(6), $aRet[1])
Else
$dw = _WinAPI_GetSystemMetrics(16) - 2 * _WinAPI_GetSystemMetrics(6)
$dh = _WinAPI_GetSystemMetrics(17) - 2 * _WinAPI_GetSystemMetrics(7)
ShellExecute ($eXn, string($dw) & "/" & string($dh))
WinMove (WinWaitactive($lPn), "", $aRet[0] - 2 * _WinAPI_GetSystemMetrics(6), $aRet[1] + _WinAPI_GetSystemMetrics(7))
EndIf
$GUI = WinGetHandle ($lPn)
_WinAPI_SetWindowLong($GUI, $GWL_STYLE, bitor(_WinAPI_getWindowLong($GUI, $GWL_STYLE), $WS_CLIPCHILDREN))
Opt("WinTitleMatchMode", 1)
$oWordApp = _Word_Create (0, 0)
$hWnd = WinWait ("Microsoft Word")
_WinAPI_SetWindowLong($hWnd, $GWL_EXSTYLE, $WS_EX_TOOLWINDOW)
_Word_DocOpen($oWordApp, @ScriptDir & "\test.docx")
_WinAPI_SetWindowLong($hWnd, $GWL_STYLE, $WS_POPUP)
_WinAPI_MoveWindow($hWnd, 0, 0, 200, 200)
_WinAPI_SetWindowLong($hWnd, $GWL_STYLE, BitOR($WS_CHILD, $WS_TABSTOP, $WS_VISIBLE))
_WinAPI_SetParent($hWnd, $GUI)
_WinAPI_MoveWindow($hWnd, 0, 61, $dw - $dw / 5, $dh - 61)
_WinAPI_UpdateWindow($GUI)
_WinAPI_UpdateWindow($hWnd)
;$iTimer = TimerInit()
_WinAPI_InvalidateRect($GUI)
While WinExists($lPn)
;If TimerDiff($iTimer) >= 500 Then
; $iTimer = TimerInit()
; _WinAPI_InvalidateRect($GUI)
;EndIf
Wend
_Word_Quit($oWordApp)
Else
WinSetState ($lPn, '', @SW_SHOW & @SW_RESTORE)
WinActivate($lPn)
EndIf
Func _GetDesktopWorkArea()
Local Const $SPI_GETWORKAREA = 48
Local $sRect = DllStructCreate($tagRECT)
If _WinAPI_SystemParametersInfo($SPI_GETWORKAREA, 0, DllStructGetPtr($sRect)) Then
Local $aRet[4] = [ _
DllStructGetData($sRect, "Left"), _
DllStructGetData($sRect, "Top"), _
DllStructGetData($sRect, "Right"), _
DllStructGetData($sRect, "Bottom")]
Return SetError(0, 0, $aRet)
EndIf
Return SetError(1, 0, 0)
EndFunc ;==>_GetDesktopWorkArea
Вкратце что делаем:
1. При открытии окна блица надо добавить к нему стиль WS_CLIPCHILDREN операцией бинарного ИЛИ к уже существующим стилям - это для того, чтобы блиц не перерисовывал область дочернего окна.
2. При запуске потенциального дочернего окна назначаем ему стиль WS_EX_TOOLWINDOW, чтобы он не мелькал в панели задач, а потом назначаем WS_POPUP, чтобы убрать рамку.
3. Переназначаем дочернему окну стили WS_CHILD и WS_VISIBLE - дочернее и видимое (тк по умолчанию окно будет скрыто после предыдущих операций).
4. Назначаем родителя SetParent, обновляем окна, посылая ему WM_PAINT, тут начинается лабуда из-за очередности прорисовки окон в винде, чтобы этой лабуды не было, назначаем InvalidateRect.
PS. Универсальную dll не стал делать, т.к. каждое приложение имеет свои особенности, лучше подгонять отдельно - править скрипт autoit.
PS2. Почему блиц? Мне нужна 3D сцена, которая создается считывая данные из документа Word, которые при этом правятся. В общем, из 3D движков я работал только с блицем, мне проще взять его и не париться.
Потестите пример (run.exe), у всех дочернее окно ворда нормально отрисовывается?
Проверял на Win 7 и 10 х64, офис 2010.
|