PureBasic - форум

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

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


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Как установить размер MDIChild окна ?


Как установить размер MDIChild окна ?

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

1

Приветствую!
Решил изучить PureBasic и столкнулся с проблемой, как можно выставить размер MDIChild окна, без использования WinAPI.

Если используем MDIGadget и

Код:
AddGadgetItem(#MDIGadget, #MDIChild, "Внутреннее окно",0,#PB_Window_BorderLess | 
#PB_Window_SystemMenu | #PB_Window_TitleBar)

то окно создается громадное. Если к этому окну применить ResizeWindow(#MDIChild,286,203,400,200), то окно создается нужного размера, но возникает проблема дергания окна. Выглядит это безобразно и чудовищно.

Вопрос 1: Как можно корректно выставить размер MDIChild окна в данном случае без дергания?

----------------

Есть второй способ, открыть два окна с помощью функции OpenWindow:

Код:
; константы
Enumeration
  #Main = 0
  #MDIChild = 1
  #MenuItem_New
EndEnumeration

; процедура внутреннего окна
Procedure Child()
  OpenWindow(#MDIChild, 0, 0, 400, 200, "Внутреннее окно", #PB_Window_BorderLess | 
#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_TitleBar,WindowID(#Main))
EndProcedure
  
  ; запускаем программу
  If OpenWindow(#Main, 0, 0, 640, 480, "Главное окно", #PB_Window_SystemMenu | 
#PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget 
| #PB_Window_Maximize)
    SetWindowColor(#Main, $808080)
    If CreateMenu(#Main, WindowID(#Main))
      MenuTitle("Меню 1")
      MenuTitle("Меню 2")
        MenuItem(#MenuItem_New, "Подпункт 1")
        MenuItem(1, "Подпункт 2")
    EndIf
    
   ; цикл
   Repeat 
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
         Select EventWindow()
            Case #Main
               End
            Default
               CloseWindow(EventWindow())
         EndSelect
      Case #PB_Event_Menu
         Select EventMenu()
           Case #MenuItem_New
                 Child()
         EndSelect
   EndSelect
   Until Quit = 1
   
 EndIf

Здесь собственно все в порядке за одним исключением. Окно #MDIChild легко накрывает меню и выходит за пределы окна #Main.

Вопрос 2: Как сделать корректное MDI с помощью функции OpenWindow, чтобы окно #MDIChild не могла накрывать меню и выходить за пределы окна #Main ?

0

2

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

то окно создается громадное. Если к этому окну применить ResizeWindow(#MDIChild,286,203,400,200), то окно создается нужного размера, но возникает проблема дергания окна. Выглядит это безобразно и чудовищно.

Создаем невидимое окно, изменяем размеры и отображаем - ничего не дергается.

Код:
#Main = 0
#MDIChild = 1
If OpenWindow(#Main, 0, 0, 400, 300, "MDIGadget", #PB_Window_Invisible|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MaximizeGadget)
  If CreateMenu(#Main, WindowID(#Main))
    MenuTitle("Menu index 0")
    MenuTitle("MDI windows menu")
    MenuItem(0, "self created item")
    MenuItem(1, "self created item")
    MDIGadget(0, 0, 0, 0, 0, 1, 2, #PB_MDI_AutoSize)
       AddGadgetItem(0, #MDIChild, "child window - 1", 0, #PB_Window_Invisible)
       AddGadgetItem(0, #MDIChild+1, "child window  - 2", 0, #PB_Window_Invisible|#PB_Window_MinimizeGadget)
       
       ResizeWindow(#MDIChild, 10, 10, 120, 100)
       ResizeWindow(#MDIChild+1, 50, 50, 140, 200)
       
       HideWindow(#MDIChild, 0)
       HideWindow(#MDIChild+1, 0)
    
    UseGadgetList(WindowID(#Main)) ; go back to the main window gadgetlist
  EndIf
  
  HideWindow(#Main, 0)
  Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Javaca написал(а):

Как сделать корректное MDI с помощью функции OpenWindow, чтобы окно #MDIChild не могла накрывать меню и выходить за пределы окна #Main ?

Как вариант, установить окном-родителем, главное окно.

Код:
; константы
Enumeration
  #Main = 0
  #MDIChild = 1
  #MenuItem_New
EndEnumeration

; процедура внутреннего окна
Procedure Child()
  OpenWindow(#MDIChild, 0, 0, 400, 200, "Внутреннее окно", #PB_Window_Invisible | #PB_Window_WindowCentered | #PB_Window_SystemMenu | #PB_Window_TitleBar,WindowID(#Main))
  SetParent_(WindowID(#MDIChild), WindowID(#Main))
  HideWindow(#MDIChild, 0)
EndProcedure
  
  ; запускаем программу
  If OpenWindow(#Main, 0, 0, 640, 480, "Главное окно", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_Maximize)
    SetWindowColor(#Main, $808080)
    If CreateMenu(#Main, WindowID(#Main))
      MenuTitle("Меню 1")
      MenuTitle("Меню 2")
        MenuItem(#MenuItem_New, "Подпункт 1")
        MenuItem(1, "Подпункт 2")
    EndIf
    
   ; цикл
   Repeat 
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
         Select EventWindow()
            Case #Main
               End
            Default
               CloseWindow(EventWindow())
         EndSelect
      Case #PB_Event_Menu
         Select EventMenu()
           Case #MenuItem_New
                 Child()
         EndSelect
   EndSelect
   Until Quit = 1
   
 EndIf

0

3

Благодарю Петр, но по первому варианту, окно дергается. Вариант с сокрытием окна я пробывал с самого начала еще до публикации своего сообщения на этом форуме, результатов не дает. Сами попробуйте на моем примере. Вызов окна осуществляется пунктом меню "Подпункт 1".  :flag:
По второму варианту Вы используете функцию WinAPI - SetParent, на Линуксе работать не будет. В самом начала своего сообщения я указал "без использования WinAPI"  :rolleyes:

Пример с MDIGadget:

Код:
Enumeration
  #Main = 0
  #MDIChild = 1
  #MDIGadget
  #MenuItem_New
EndEnumeration

; процедура внутреннего окна
Procedure Child()
  AddGadgetItem(#MDIGadget, #MDIChild, "Внутреннее окно",0,#PB_Window_Invisible | #PB_Window_BorderLess 
| #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_TitleBar)
  ResizeWindow(#MDIChild,286,203,400,200)
  HideWindow(#MDIChild,0)
  ;ResizeWindow(#MDIChild,286,203,400,200)
  ; рабочий вариант
  ;OpenWindow(#MDIChild, 0, 0, 400, 200, "Внутреннее окно", #PB_Window_BorderLess | #PB_Window_ScreenCentered 
| #PB_Window_SystemMenu | #PB_Window_TitleBar,WindowID(#Main))
  ;SetParent_(WindowID(#MDIChild), WindowID(#Main))
  ;HideWindow(#MDIChild, 0)
EndProcedure

  
  ; запускаем программу
  If OpenWindow(#Main, 0, 0, 640, 480, "Главное окно", #PB_Window_SystemMenu | #PB_Window_ScreenCentered 
| #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget 
| #PB_Window_Maximize)
    ;SetWindowColor(#Main, $808080)
    If CreateMenu(#Main, WindowID(#Main))
      MenuTitle("Файл")
      MenuTitle("Меню 2")
        MenuItem(#MenuItem_New, "Подпункт 1")
        MenuItem(1, "Подпункт 2")
        
        MDIGadget(#MDIGadget, 0, 0, 400, 200, 0, 0, #PB_MDI_AutoSize)

      ;UseGadgetList(WindowID(#Main)) 
    EndIf
    
   ; цикл
   Repeat 
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
         Select EventWindow()
            Case #Main
               End
            Default
               CloseWindow(EventWindow())
         EndSelect
      Case #PB_Event_Menu
         Select EventMenu()
           Case #MenuItem_New
                 Child()
         EndSelect
   EndSelect
   Until Quit = 1
   
 EndIf

0

4

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

По второму варианту Вы используете функцию WinAPI - SetParent, на Линуксе работать не будет

Javaca
MDIGadget - в линуксе несуществует! В справке написано онли вин. :dontknow:

0

5

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

MDIGadget - в линуксе несуществует! В справке написано онли вин.

Очень странно, в одном месте написано MDIGadget поддерживается платформами: Windows, Linux, MacOS X

http://www.purearea.net/pb/english/manu … adget.html

В другом месте написано не поддерживается:  :canthearyou:

http://www.purebasic.com/documentation/ … adget.html

Ну да Бог с ним с MDIGadget, функция OpenWindow поддерживается вроде везде.
Как тогда не используя функцию WinAPI - SetParent, довести до ума MDI по второму варианту?  :writing:

0

6

А если попробовать поискать аналог WinAPI функции SetParent для Linux (GTK)?

0

7

Пётр написал(а):

А если попробовать поискать аналог WinAPI функции SetParent для Linux (GTK)?

Для GTK ничего не нашел, для QT есть. В любом случае вывод очевиден, что кроссплатформенного MDI окна в PureBasic стандартными средствами сделать невозможно !!!

Библиотека Qt:

Код:
void setParent ( QWidget * parent )
void setParent ( QWidget * parent, Qt::WindowFlags f )

Вот еще нашел в Инете !

Библиотека wxWidgets:

Код:
myParent = new wxMDIParentFrame( (wxWindow*)NULL, TOP_PARENT, "главное окно" ); 
myChild = new wxMDIParentFrame( myParent, CHILD_MDI, "дочернее" );

Нашел wxWidget Purebasic Port для Windows и Linux, но скачать мне не удалось. Не хватило видимо скорости. Может кому удастся скачать и переложить в другое место:
http://www.realsource.de/index.php/down … basic-port

Пример использования библиотеки wxWidgets на PureBasic:

Код:
XIncludeFile #PB_Compiler_Home + "Include\inc.wx.pbi"

Enumeration
   #CONTROL
EndEnumeration 

Enumeration
   #WINDOW_TEST
EndEnumeration 

Global APP.i   
   
Procedure OnInit()
   Protected frame
   Protected control
      
   ; fenster erstellen
   frame = wxFrame()
   control = wxCheckBox( )
   wxFrame_Create(frame, #WINDOW_TEST, 1, "Test", wxSize(-1,-1), wxSize(-1,-1), #wxDEFAULT_FRAME_STYLE, "frame")
   wxCheckBox_Create (control,  frame ,  #CONTROL,  "I'm a checkbox" ,  wxSize(-1, -1),  wxSize(-1, -1),  0,  0,  "checkBox")
  wxCheckBox_SetValue(control, #True)
   
   ; Frame anzeigen
   wxWindow_Show(frame,#True)   
   
   ProcedureReturn wxApp_OnInit(APP)
EndProcedure

Procedure OnExit()   
   ProcedureReturn wxApp_OnExit(APP)
EndProcedure   

Procedure Main()   
   APP    = wxApp() 
   wxApp_RegisterVirtual(app,@OnInit(),@OnExit())   
   wxApp_Run(0,0)   
EndProcedure:Main()

0

8

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

Для GTK ничего не нашел

Я думаю что функция все же существует.
Можно попробовать спросить здесь http://www.purebasic.fr/english/viewforum.php?f=15

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

Нашел wxWidget Purebasic Port для Windows и Linux, но скачать мне не удалось.

Нормально скачалось http://depositfiles.com/files/e8ww980k8

0

9

Пётр написал(а):

Нормально скачалось http://depositfiles.com/files/e8ww980k8

Благодарю, по Вашей ссылке с депозита нормально скачалось, а оттуда на 5 мегабайтах рвалась закачка. Все примеры прилагаемые к библиотеке wxWidget скомпилировались на ура, вес скомпилированной программы от 4 Кб. Единственно, что нужно для работы скомпилированной программы - это установленные в Windows (или просто положить рядом с компилированной программой) - Microsoft® C Runtime Library (msvcr71.dll) и Библиотека wxWidget (wx-c.dll) Теперь можно попробывать написать кроссплатформенное MDI окно.  :hobo:

Пётр написал(а):

Я думаю что функция все же существует.
Можно попробовать спросить здесь http://www.purebasic.fr/english/viewforum.php?f=15

Если Вас не затруднит и Вы обладаете нормальным английским, то попробывать спросить можно  :glasses:

0

10

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

Если Вас не затруднит и Вы обладаете нормальным английским

К сожалению, мой английский оставляет желать лучшего и обычно пользуюсь гугло-переводчиком.

0

11

Пётр написал(а):

Я думаю что функция все же существует.

Похоже ?  :yep:

void gtk_widget_reparent (GtkWidget *widget, GtkWidget *new_parent)

0

12

Кто-нибудь знает, почему выползает Ошибка: Невозможен доступ к памяти (ошибка записи по адресу 2415957050) ?

Пытаюсь сделать MDI окно с использованием библиотеки wxWidget.

Код:
XIncludeFile ( #PB_Compiler_Home + "include/inc.wx.pbi")

EnableExplicit

Global APP.i	
	
Procedure OnInit()
  Protected frame
  Protected mdiparent
  
  frame = wxFrame()
  wxFrame_Create(frame, 0, -1, "", wxSize(-1,-1), wxSize(640,480), #wxDEFAULT_FRAME_STYLE, "frame")    
  wxFrame_Maximize (frame, #True)
  
  mdiparent = wxMDIParentFrame()
  ;wxMDIParentFrame_RegisterVirtual(mdiparent, wxMDIParentFrame_OnCreateClient(mdiparent))
  ;wxMDIParentFrame_OnCreateClient(mdiparent)
	wxMDIParentFrame_Create(frame, 0, -1, "Основное окно", wxSize(-1,-1), wxSize(640,480), #wxDEFAULT_FRAME_STYLE, "frame")

	wxWindow_Show(frame,#True)
	
	ProcedureReturn wxApp_OnInit(app)
	
EndProcedure

Procedure OnExit()	
	ProcedureReturn wxApp_OnExit(app)
EndProcedure	

Procedure Main()	
	app 	= wxApp() 
	wxApp_RegisterVirtual(app,@OnInit(),@OnExit())	
	wxApp_Run(0,0)	
EndProcedure:Main()

0

13

Зашел на сайт http://vwx-cdev.sourceforge.net/ , скачал пакет Visual WX-C Developer из которого взял wx-c.dll размером меньше в два раза, чем dll которая шла с wxWidget Purebasic Port для Windows и Linux. Скомпилировал свой пример который выше, запустил скомпилированный пример, закрыл его и никаких ошибок  %-)

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Как установить размер MDIChild окна ?