1

Тема: AHK: MsgBox - положение окна на экране

Есть ли способ вывода окна сообщения MsgBox не в центре, как по умолчанию, а в нужном месте?
     Можно, конечно, переместить окно по команде WinMove, но хотелось бы, чтобы окно появлялось сразу в нужном месте.

2

Re: AHK: MsgBox - положение окна на экране

Посредством AHK — никак, но можно создать своё окно вместо MsgBox.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: MsgBox - положение окна на экране

Ясно, спасибо!

4

Re: AHK: MsgBox - положение окна на экране

Немного баловства :

#NoTrayIcon
SetBatchLines, -1
Str:="Бегущая строка... "
StrLenght:=StrLen(Str)
SetTimer, ChangeMsgBox, 1
MsgBox,0x40004,Видоизменённый MsgBox,
SetTimer, ScrollText,Off
ExitApp

ChangeMsgBox:
if !(hMsgBox:=DllCall("FindWindow","str","#32770","str","Видоизменённый MsgBox"))
return
SetTimer, ChangeMsgBox, Off
DllCall("SetWindowLong","uint",hMsgBox,"int",-20,"uint",DllCall("GetWindowLong","uint",hMsgBox,"int",-20)|WS_EX_TOOLWINDOW:=0x80) ; ???
DllCall("SetWindowLong","uint",hMsgBox,"int",-16,"uint",DllCall("GetWindowLong","uint",hMsgBox,"int",-16)^WS_CAPTION:=0xC00000)
DllCall("SetWindowPos","uint",hMsgBox,"uint",0,"int",A_ScreenWidth/3,"int",A_ScreenHeight/2-120,"int",A_ScreenWidth/3,"int",240,"uint",0x40)
ControlGet, hbt1, Hwnd,,Button1, ahk_id %hMsgBox%
ControlGet, hbt2, Hwnd,,Button2, ahk_id %hMsgBox%
DllCall("SetWindowPos","uint",hbt1,"uint",0,"int",-3,"int",208-3,"int",A_ScreenWidth/6,"int",30,"uint",0x40)
DllCall("SetWindowPos","uint",hbt2,"uint",0,"int",A_ScreenWidth/6-3,"int",208-3,"int",A_ScreenWidth/6,"int",30,"uint",0x40)
SetTimer, ScrollText,250
Return

ScrollText:
StartPos += StartPos<StrLenght ? 1 : -StrLenght+1
ScrlText:=SubStr(Str,StartPos) . SubStr(Str,1,StartPos)
DllCall("SendMessage","uint",hbt2,"uint",0xC,"uint",0,"uint",&ScrlText)
Return

/*
SWP_SHOWWINDOW   = 0x40
WM_SETTEXT       = 0xC
*/

5

Re: AHK: MsgBox - положение окна на экране

Спасибо, интересно! Только заголовок у него не появился.
То-есть, просто сменить позицию можно так:

SetTimer, ChangePos, 1
MsgBox,, Заголовок, Текст
Return

ChangePos:
   if !hMsgBox:=DllCall("FindWindow", Str, "#32770", Str, "Заголовок")
      Return
      
   DllCall("SetWindowPos", UInt, hMsgBox, UInt, 0, Int, 100, Int, 100, Int, 0, Int, 0, UInt, SWP_NOSIZE := 1)
   SetTimer, ChangePos, Off
   Return

Получается, что FindWindow() находит окно раньше, чем оно появляется на экране, в отличие от WinExist()?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6

Re: AHK: MsgBox - положение окна на экране

Хотя и просто так получается:

SetTimer, ChangePos, 1
MsgBox,, Заголовок, Текст
Return

ChangePos:
   DetectHiddenWindows, On
   if !hMsgBox := WinExist("Заголовок ahk_class #32770")
      Return
      
   WinMove, ahk_id %hMsgBox%,, 100, 100
   SetTimer, ChangePos, Off
   Return
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7 (изменено: Александр_, 2011-11-21 03:50:42)

Re: AHK: MsgBox - положение окна на экране

teadrinker пишет:

Получается, что FindWindow() находит окно раньше, чем оно появляется на экране, в отличие от WinExist()?

Как повезёт. Если успеет отработать в промежутке между созданием окна и вызовом ShowWindow, то прокатит .
Ну вообще не хорошо таймерами кидаться- не надёжно и систему напрягает. Нужно поставить локальный хук на WH_CBT и обрабатывать код LPCBT_CREATEWND. В lParam будет ссылка на структуру CBT_CREATEWND, в которой будет ссылка структуру CREATESTRUCT, в которой будут данные о положении окна, которые можно подменить. Ссылка на имя класса в этой структуре скорее всего будет невалидной, это отмечено в документации, поэтому нужно его отдельно получать.

hhook:=DllCall("SetWindowsHookEx", "int", 5, "uint", RegisterCallback("HookProc", "", 3), "uint", 0, "uint", DllCall("GetCurrentThreadId", "uint"), "uint")
msgbox 111111111111111
msgbox 222222222222222
DllCall("UnhookWindowsHookEx", "uint", hhook)
ExitApp
return

HookProc(code,wParam,lParam)
{
	if (code=3) ;если создаётся создаётся
	{
	   VarSetCapacity(Class, 14, 0) ; память под имя класса окна
	   DllCall("GetClassName", "uint", wParam, "uint", &Class, "uint", 7) ;получаем имя класса
	   ClassName:=StrGet(&Class, 6) ;можно длину не указывать, строка с нулём на конце
	   if (ClassName="#32770") ;если MessageBox
	   {
	      NumPut(0,NumGet(lParam|0), 24) ;игрек
		  NumPut(0,NumGet(lParam|0), 28) ;икс
	   }
	}
	return DllCall("CallNextHookEx", "uint", hhook, "uint", code, "uint", wParam, "uint", lParam)
}

P.S. Лучше всё-таки своё окно сделать

8

Re: AHK: MsgBox - положение окна на экране

Александр_ пишет:

Нужно поставить локальный хук на WH_CBT...

Спасибо, логично.

Александр_ пишет:

Лучше всё-таки своё окно сделать

Мне тоже показалось, что проще.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder