PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Выбор монитора Окна


Выбор монитора Окна

Сообщений 1 страница 10 из 10

1

Подскажите, чем можно определить монитор для каждого окна?
Помню что всё просто, но не могу вспомнить.

0

2

https://learn.microsoft.com/en-us/windo … fromwindow

+1

3

Код:
; Определяет монитор окна
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

+1

4

Ещё один вариант. Примечателен тем, что, когда окно на двух смежных мониторах, выбирается тот, над которым окно находится большей своей частью. Первый вариант, работает по другому на границах, и неправильно, на самой левой и самой верхней.
В общем, это поле для фантазии, какие нужны условия, такие и можно задать.

Код:
; Определяет монитор окна
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)

0

5

Я так понял нет возможности сразу указать окну на каком рабочем столе появится по середине.
Но можно узнать сколько рабочих столов и просто учесть длину всего графического пространства для расположения окна.

0

6

Ev3658 написал(а):

Я так понял нет возможности сразу указать окну на каком рабочем столе появится по середине.
Но можно узнать сколько рабочих столов и просто учесть длину всего графического пространства для расположения окна.

Да, в нативе этого нет. Но можно примерно так:

Код:
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)

0

7

Спасибо!
Блин, век живи, век учись ))) То-есть Macro можно перехватить операторы PureBasic  8-)

Код:
Procedure _OpenWindow.....
Macro OpenWindow : _OpenWindow : EndMacro

0

8

Вот ещё пример нахождения номера рабочего стола, который имеет наибольшую площадь пересечения с прямоугольником указанного окна:

Код:
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)

0

9

Ev3658 написал(а):

Блин, век живи, век учись ))) То-есть 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

Написал вот вам примеры просто ради интереса, а сегодня оно мне самому понадобилось. Прямо, ваш запрос, под мою задачу  8-)

0

10

Webarion написал(а):

....Прямо, ваш запрос, под мою задачу

У меня тут вообще свалилось спасение ситуации.
Вообщем как-то с другом разговаривали три месяца назад, типа в кафе можно лотерею сделать с использованием бочонков "Лото". Ну пообщались и забыли.
Он как-то там живёт, в кафе суетится, а я как-то отдельно.
Тут захожу на днях, вижу что уже приступили к реализации и срок то всего неделя. Студент на Питоне создал графический генератор билетов, просто исполняемый EXE файл, а в целом игровой системы для ТВ и тому подобного нет.
Тут-то и свалилось на меня всё. В итоге за пару дней сделал генератор ЛОТО билетов под печать А4, всё как надо генерирует)))) правильно.
И за пару дней графический интерфейс.

Использовал адаптер HDMI в антенный провод (формат DVB-C - кабельное ТВ) и на 4 монитора транслировал второй экран ПК. Управление всем этим из другого окна на первом экране.
Получилось круто, но я уже стар для такого спортивного программирования.

Вот тест на одном мониторе:

https://forumupload.ru/uploads/0009/ae/28/591/t409159.jpg

А вот такой генератор хаоса получился у меня, использовал криптографический рандомайзер (но и он не даёт нужного хаоса):

https://forumupload.ru/uploads/0009/ae/28/591/t370656.jpg

Студент немного спёкся с этим Питоном, одно дело найти код для генерации этих билетов, другое дело сделать его правильным - и тут нужны мозги особой математики.

Оказывается в ЛОТО билетах каждый вертикальный ряд имеет 9 цифр, а последний 10 цифр. К каждом горизонтальном ряду не более 5 цифр и 4 свободные ячейки. Не должно быть 3 пустых вертикальных ячейки.
Но хлеще всего генерировать два билета в одном. Точней ЛОТО билеты имеют 2шт. сразу и в них нет совпадения цифр. Я от души оторвался в Qbasic на PureBasic  :D

Проект не коммерческий, но зато зачётно показал возможности 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 numm

     If 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))
     Return

Dim 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)

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Выбор монитора Окна