Подскажите, чем можно определить монитор для каждого окна?
Помню что всё просто, но не могу вспомнить.
Выбор монитора Окна
Сообщений 1 страница 10 из 10
Поделиться103.02.2024 15:01:44
Поделиться303.02.2024 19:04:41
; Определяет монитор окна Procedure GetDesktopWindow( Window ) For desktop = 0 To ExamineDesktops() - 1 Protected wx = WindowX(Window), wy = WindowY(Window), dx = DesktopX(desktop), dy = DesktopY(desktop) If wx >= dx And wx < dx + DesktopWidth(desktop) And wy >= dy And wy < dy + DesktopHeight(desktop) ProcedureReturn desktop EndIf Next ProcedureReturn -1 EndProcedure ; Пример #Win = 0 Procedure Demo() Define Desktop = GetDesktopWindow(#Win), Num$, Depth$, Freq$, Name$ If Desktop >= 0 Num$ = Str(Desktop) Depth$ = Str( DesktopDepth(Desktop) ) Freq$ = Str( DesktopFrequency(Desktop) ) Name$ = DesktopName(Desktop) Else Num$ = "none" : Depth$ = Num$ : Freq$ = Num$ : Name$ = Num$ EndIf SetGadgetText( 0, "Desktop: " + Num$ ) SetGadgetText( 1, "Глубина цвета: " + Depth$ ) SetGadgetText( 2, "Частота кадров: " + Freq$ ) SetGadgetText( 3, "Имя: " + Name$ ) EndProcedure If OpenWindow( #Win, 0, 0, 200, 200, "Пример", #PB_Window_SystemMenu | #PB_Window_ScreenCentered ) TextGadget( 0, 10, 10, 250, 20, "" ) TextGadget( 1, 10, 30, 250, 20, "" ) TextGadget( 2, 10, 50, 250, 20, "" ) TextGadget( 3, 10, 70, 250, 20, "" ) Demo() Repeat Define Event = WaitWindowEvent() If Event = #PB_Event_MoveWindow Demo() EndIf Until Event = #PB_Event_CloseWindow EndIf
Поделиться404.02.2024 01:18:09
Ещё один вариант. Примечателен тем, что, когда окно на двух смежных мониторах, выбирается тот, над которым окно находится большей своей частью. Первый вариант, работает по другому на границах, и неправильно, на самой левой и самой верхней.
В общем, это поле для фантазии, какие нужны условия, такие и можно задать.
; Определяет монитор окна Procedure GetDesktopWindow( Window ) Protected minDeskX = 0, minDeskY = 0, OldMarker = 0, Result = -1 For desktop = 0 To ExamineDesktops() - 1 Protected Marker = 0 Protected wX = WindowX(Window), wY = WindowY(Window) Protected wW = WindowWidth(Window), wH = WindowHeight(Window) Protected wCenterX = wX + ( wW / 2 ), wCenterY = wY + ( wH / 2 ) Protected dL = DesktopX(desktop), dT = DesktopY(desktop) Protected dR = dL + DesktopWidth(desktop), dB = dT + DesktopHeight(desktop) If dL < minDeskX : minDeskX = dL : EndIf ; ищем самую левую координату на всех мониторах If dT < minDeskY : minDeskY = dT : EndIf ; ищем самую верхнюю координату на всех мониторах If wCenterX > dL And wCenterX < dR : Marker + 1 : EndIf If wCenterY > dT And wCenterY < dB : Marker + 1 : EndIf If wX + wW > dL And wX < dR : Marker + 1 : EndIf If wY + wH > dT And wY < dB : Marker + 1 : EndIf If Marker > OldMarker OldMarker = Marker Result = desktop EndIf Next ProcedureReturn Result EndProcedure ; Пример #Win = 0 Procedure Demo() Define Desktop = GetDesktopWindow(#Win), Result$ = "" If Desktop >= 0 Result$ + "Desktop: " + Str(Desktop) + #CRLF$ Result$ + "Глубина цвета: " + Str( DesktopDepth(Desktop) ) + #CRLF$ Result$ + "Частота кадров: " + Str( DesktopFrequency(Desktop) ) + #CRLF$ Result$ + "Имя: " + DesktopName(Desktop) Else Result$ = "Окно вне всех мониторов" EndIf ClearDebugOutput() Debug Result$ SetGadgetText( 0, Result$) EndProcedure ;- OpenWindow If OpenWindow( #Win, 0, 0, 200, 200, "Пример", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget ) TextGadget( 0, 10, 10, 180, 180, "" ) Demo() Repeat Define Event = WaitWindowEvent() If Event = #PB_Event_MoveWindow Demo() EndIf Until Event = #PB_Event_CloseWindow EndIf
Отредактировано Webarion (04.02.2024 01:45:52)
Поделиться504.02.2024 10:41:11
Я так понял нет возможности сразу указать окну на каком рабочем столе появится по середине.
Но можно узнать сколько рабочих столов и просто учесть длину всего графического пространства для расположения окна.
Поделиться604.02.2024 11:16:36
Я так понял нет возможности сразу указать окну на каком рабочем столе появится по середине.
Но можно узнать сколько рабочих столов и просто учесть длину всего графического пространства для расположения окна.
Да, в нативе этого нет. Но можно примерно так:
Procedure _OpenWindow( Window, X, Y, Width, Height, Title$, Flags = #PB_Window_SystemMenu, ParentWindowID = 0, NumDesktop = 0 ) If NumDesktop >= 0 And NumDesktop < ExamineDesktops() X + DesktopX(NumDesktop) : Y + DesktopY(NumDesktop) If Flags & #PB_Window_ScreenCentered X + ( DesktopWidth(NumDesktop) / 2 ) - ( Width / 2 ) Y + ( DesktopHeight(NumDesktop) / 2 ) - ( Height / 2 ) Flags ! #PB_Window_ScreenCentered EndIf EndIf ProcedureReturn OpenWindow( Window, X, Y, Width, Height, Title$, Flags, ParentWindowID ) EndProcedure Macro OpenWindow : _OpenWindow : EndMacro ; Пример Define DesktopNum = 1 ; указать номер рабочего стола If OpenWindow( 0, 0, 0, 200, 200, "Пример", #PB_Window_SystemMenu | #PB_Window_ScreenCentered, 0, DesktopNum ) Repeat Define Event = WaitWindowEvent() Until Event = #PB_Event_CloseWindow EndIf
Отредактировано Webarion (04.02.2024 22:18:15)
Поделиться704.02.2024 11:43:20
Спасибо!
Блин, век живи, век учись ))) То-есть Macro можно перехватить операторы PureBasic
Procedure _OpenWindow..... Macro OpenWindow : _OpenWindow : EndMacro
Поделиться804.02.2024 11:58:19
Вот ещё пример нахождения номера рабочего стола, который имеет наибольшую площадь пересечения с прямоугольником указанного окна:
Procedure _Min( a, b ) : If( a < b ) : ProcedureReturn a : EndIf : ProcedureReturn b : EndProcedure Procedure _Max( a, b ) : If( a < b ) : ProcedureReturn b : EndIf : ProcedureReturn a : EndProcedure ; Возвращает номер рабочего стола, который имеет наибольшую площадь пересечения с прямоугольником указанного окна Procedure DesktopFromWindow( Window ) Protected wl = WindowX(Window) : wr = wl + WindowWidth(Window) Protected wt = WindowY(Window) : wb = wt + WindowHeight(Window) Protected parea = 0, result = -1 For desk = 0 To ExamineDesktops() - 1 Protected dl = DesktopX(desk) : dr = dl + DesktopWidth(desk) Protected dt = DesktopY(desk) : db = dt + DesktopHeight(desk) If dr > wl And wr > dl And db > wt And wb > dt ; если прямоугольники рабочего стола и окна пересекаются Protected area = ( _Min(dr, wr)-_Max(dl, wl) ) * ( _Min(db, wb)-_Max(dt, wt) ) ; площадь пересечения окна и рабочего стола If area > parea : result = desk : EndIf parea = area EndIf Next ProcedureReturn result EndProcedure ; Пример #Win = 0 Procedure Demo() Define Desktop = DesktopFromWindow(#Win), Result$ = "" If Desktop >= 0 Result$ + "Номер рабочего стола: " + Str(Desktop) + #CRLF$ Result$ + "Имя: " + DesktopName(Desktop) Else Result$ = "Окно вне всех рабочих столов" EndIf ClearDebugOutput() Debug Result$ SetGadgetText( 0, Result$) EndProcedure ;- OpenWindow If OpenWindow( #Win, 0, 0, 200, 200, "Пример", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget ) TextGadget( 0, 10, 10, 180, 180, "" ) Demo() Repeat Define Event = WaitWindowEvent() If Event = #PB_Event_MoveWindow Demo() EndIf Until Event = #PB_Event_CloseWindow EndIf
Отредактировано Webarion (04.02.2024 13:01:47)
Поделиться905.02.2024 23:59:45
Блин, век живи, век учись ))) То-есть Macro можно перехватить операторы PureBasic
Да, это очень удобно. Например, у меня так инициализируется графический интерфейс:
Procedure _WaitWindowEvent() If Not INIT : Draw_All_Controls() : INIT = #True : EndIf ProcedureReturn WaitWindowEvent() EndProcedure Macro WaitWindowEvent : _WaitWindowEvent : EndMacro Procedure _WindowEvent() If Not INIT : Draw_All_Controls() : INIT = #True : EndIf ProcedureReturn WindowEvent() EndProcedure Macro WindowEvent() : _WindowEvent : EndMacro
Написал вот вам примеры просто ради интереса, а сегодня оно мне самому понадобилось. Прямо, ваш запрос, под мою задачу
Поделиться1010.02.2024 11:12:33
....Прямо, ваш запрос, под мою задачу
У меня тут вообще свалилось спасение ситуации.
Вообщем как-то с другом разговаривали три месяца назад, типа в кафе можно лотерею сделать с использованием бочонков "Лото". Ну пообщались и забыли.
Он как-то там живёт, в кафе суетится, а я как-то отдельно.
Тут захожу на днях, вижу что уже приступили к реализации и срок то всего неделя. Студент на Питоне создал графический генератор билетов, просто исполняемый EXE файл, а в целом игровой системы для ТВ и тому подобного нет.
Тут-то и свалилось на меня всё. В итоге за пару дней сделал генератор ЛОТО билетов под печать А4, всё как надо генерирует)))) правильно.
И за пару дней графический интерфейс.
Использовал адаптер HDMI в антенный провод (формат DVB-C - кабельное ТВ) и на 4 монитора транслировал второй экран ПК. Управление всем этим из другого окна на первом экране.
Получилось круто, но я уже стар для такого спортивного программирования.
Вот тест на одном мониторе:
А вот такой генератор хаоса получился у меня, использовал криптографический рандомайзер (но и он не даёт нужного хаоса):
Студент немного спёкся с этим Питоном, одно дело найти код для генерации этих билетов, другое дело сделать его правильным - и тут нужны мозги особой математики.
Оказывается в ЛОТО билетах каждый вертикальный ряд имеет 9 цифр, а последний 10 цифр. К каждом горизонтальном ряду не более 5 цифр и 4 свободные ячейки. Не должно быть 3 пустых вертикальных ячейки.
Но хлеще всего генерировать два билета в одном. Точней ЛОТО билеты имеют 2шт. сразу и в них нет совпадения цифр. Я от души оторвался в Qbasic на PureBasic
Проект не коммерческий, но зато зачётно показал возможности PureBasic в аварийных экстремальных ситуациях. А то мне говорят: "Я генератор карточек лото за пол часа написал" - ага, написал, стырил с тырнета и переделать ещё больше у него времени ушло.
Если кому надо ГЕНЕРАТОР 100 КАРТОЧЕК ЛОТО по 90 цифр и два билета в руки, угощайтесь (на 50 человек игры):
;---| Генератор Тиража
generator:repair:
For p=0 To 8
For o=0 To 2
For n=0 To 99
bilet(n,p,o)=0
Next n
Next o
Next p
haos=0
ok=1
n=0
o=0
p=0
n=0
p1=0
o1=0
n1=0
While n<100
o=0
While o<3
p=0
While p<9
ok=1
While ok<>0 ;Проверка числа на совпадение в билете
Select p
Case 0
gen=CryptRandom(8)
gen+1
Case 1
gen=CryptRandom(9)
gen+10
Case 2
gen=CryptRandom(9)
gen+20
Case 3
gen=CryptRandom(9)
gen+30
Case 4
gen=CryptRandom(9)
gen+40
Case 5
gen=CryptRandom(9)
gen+50
Case 6
gen=CryptRandom(9)
gen+60
Case 7
gen=CryptRandom(9)
gen+70
Case 8
gen=CryptRandom(10)
gen+80
EndSelect
;If P=0
; gen=CryptRandom(8)+1
; gen=gen+p*10
; Else
; gen=CryptRandom(8)+1
;EndIf
;Debug "Ячейка "+Str(p)+" Число "+Str(gen)
If gen>90
Debug "ERR"
End
EndIf
;Debug "Колонка: "+Str(p)+" Генератор: "+Str(gen)
;gen=gen+1
;------- Проверяем совпадения
For n1=n-1 To n ;Каждые два билета без повторений цифр
For o1=0 To 2
For p1=0 To 8
If n1<0 ;Если первый билет, генерируем с проверкой одного билета
If bilet(n,p1,o1)=gen
ok=2
haos+1
;Debug "Билет: "+Str(n1)+" Колонка: "+Str(p1)+" Генератор: "+Str(gen)
EndIf
Else
If bilet(n1,p1,o1)=gen
ok=2
haos+1
;Debug "Билет: "+Str(n1)+" Колонка: "+Str(p1)+" Генератор: "+Str(gen)
EndIf
EndIf
Next p1
Next o1
Next n1
If ok=1 ;Если нет совпадений
ok=0 ;Выход из цикла
bilet(n,p,o)=gen
Break
Else ;Если есть совпадения
ok=1 ;Генерируем число дальше
EndIf
Wend
p+1
Wend
o+1
Wend
n+1
Wend
Debug "Кол-во совпадений при генерации:" +Str(haos)
;If haos>220
;Goto repair
; EndIf
;------- Убрать ненужные числа
For n=0 To 99 ;Номер обрабатываемого билета
ok=1
While ok<>0
;Копируем шаблон для генерации пустых клеток
For p=0 To 8
For o=0 To 2
bilet_space(p,o)=bilet(n,p,o)
Next o
Next p
;Генерация пустых клеток
For o=0 To 2
p=0
While p<4
gen=CryptRandom(8)
If bilet_space(gen,o)<>0
bilet_space(gen,o)=0
p+1
EndIf
Wend
Next o
;Проверяем на условие отсутствия пустых 3х вертикальных клеток
For p=0 To 8
If bilet_space(p,0)=0 And bilet_space(p,0)=bilet_space(p,1) And bilet_space(p,1)=bilet_space(p,2)
ok=2
EndIf
Next p
If ok=1 ;Если всё ок, то продолжаем дальше (сохраняем билет)
For p=0 To 8 ;Копируем шаблон для генерации пустых клеток
For o=0 To 2
bilet(n,p,o)=bilet_space(p,o)
Next o
Next p
ok=0
Break
Else ;Если не прошло условие, то восстанавливаем билет и пытаемся ещё раз
ok=1
EndIf
Wend
Next n
;------- Проверка наличия всех цифр в билетеnumm=0
tm=1
While tm<90
ok=1
For n=0 To 99
For o=0 To 2
For p=0 To 8
;Debug Str(bilet(n,p,o))+"="+Str(tm)
If bilet(n,p,o)=tm
ok=0
numm+1
tm+1
EndIf
If tm=91
Break 4
EndIf
Next p
Next o
Next n
If ok=1
Debug "Нет цифры: " + Str(tm)
tm+1
EndIf
Wend
Debug "Присутствуют цифр: "+Str(numm)If numm<90 ;Переделываем если нет всех цифр в билетах
Goto repair
EndIf
;------- Проверка цифр в рядах (наличие всего десятка)For p=0 To 8
tm=1
For n=0 To 99
For o=0 To 2
If bilet(n,p,o)=tm+(p*10)
;Debug Str(tm+(p*10))+" Билет "+Str(n+1)
numm=tm+(p*10)
tm+1
EndIf
Next o
Next n
Next p
Debug nummIf numm<90
Debug "Не прошло проверку цифр десятка в ряду"
Goto repair
EndIf
;------- Совпадение цифр в билете 2 проверка (контроль)
tm=0
For n=0 To 99
For p=0 To 8
For o=0 To 2
For p1=0 To 8
For o1=0 To 2
If bilet(n,p,o)=bilet(n,p1,o1) And bilet(n,p,o)<>0 And (p<>p1 And o<>o1)
;Debug "Билет № "+Str(n)+" Число: "+Str(bilet(n,p,o))
tm+1
EndIf
Next o1
Next p1
Next o
Next p
Next n
If tm>0 ;Если есть совпадения в цифрах, переделываем всю генерацию
Debug "Билет № "+Str(n+1) +" брак. Совпадений: "+Str(tm)
Goto repair:
EndIf
Debug "Совпадений не найдено"
;End
SetWindowColor(#okno_generator, RGB(110,0,0))
ReturnDim bilet.a(100,9,3) ;Массив с билетами
Dim bilet_space.a(9,3)
Global p,p1
Global triger.a
Global o,o1
Global i
Global n,n1
Global list_a4
Global x,y
Global corr
Global gen
Global ok
Global numm
Global tm
Global haos
Отредактировано Ev3658 (10.02.2024 11:18:26)