Я вот собираюсь сделать программку, и окон в ней планируется бесчисленное множество. А именно дочерних окон как на картинке . Плюс, некоторые окна должны будут блокировать окно-родителя, а так же не позволять открывать себя более одного раза.
И сам вопрос: есть ли какая-нибудь готовая метода как это сделать?
Многооконное приложение
Сообщений 1 страница 30 из 76
Поделиться128.05.2013 22:45:06
Поделиться228.05.2013 23:01:07
Посмотри MDIGadget().
Поделиться303.06.2013 20:54:27
А как привязать одно окно к другому окну?
Поделиться403.06.2013 21:37:45
В каком плане привязать?
Если речь про MDI, то окна создаются функцией AddGadgetItem.
#Main = 0 #MDIChild = 1 If OpenWindow(#Main, 0, 0, 400, 300, "MDIGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #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) For i = 1 To 8 AddGadgetItem(0, #MDIChild+i, "child window "+Str(i)) Next ; add gadgets here... UseGadgetList(WindowID(#Main)) ; go back to the main window gadgetlist EndIf Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow EndIf
Поделиться504.06.2013 00:13:16
Пётр Как в современных IDE (окно свойств, окно элементов, окно подсказок). Которые можно отделить от главной формы или присоединить снизу, справа или слева.
Поделиться605.06.2013 07:33:12
А чье замолчали?
Поделиться705.06.2013 11:50:22
Это необходимо реализовывать в коде.
В винде готовых решений нет.
Поделиться806.06.2013 01:33:59
Пётр а как можно реализовать или что и где можно прочитать про эту реализацию.
Поделиться909.06.2013 15:33:46
Пётр Чье замолчал?
Поделиться1009.06.2013 15:37:00
Я подобное не реализовывал в своих проектах.
Поделиться1112.06.2013 21:29:43
Пётр
Я подобное не реализовывал в своих проектах.
Это понятно, а какие нибудь соображения, нету, на этот счет?
Поделиться1201.07.2013 08:07:12
Попробуй что нибудь придумать, очень интересно как это будет выглядит .
Поделиться1308.07.2013 00:17:45
Пётр
Из этого можно что нибудь придумать
Procedure WinProc(hwnd, msg, wParam, lParam) Shared *PointOldWinFunc Protected MainWin.RECT, ChildWin.RECT Protected NewPosWin.POINT, Mouse.POINT If msg = #WM_MOVE GetWindowRect_(WindowID(0), @MainWin) GetWindowRect_(WindowID(1), @ChildWin) NewPosWin\x = ChildWin\left NewPosWin\y = ChildWin\top State=0 If MainWin\left > ChildWin\left NewPosWin\x = MainWin\left State=1 EndIf If MainWin\top > ChildWin\top NewPosWin\y = MainWin\top State=1 EndIf If MainWin\right < ChildWin\right NewPosWin\x = MainWin\Right - (ChildWin\right - ChildWin\left) State=1 EndIf If MainWin\bottom < ChildWin\bottom NewPosWin\y = MainWin\bottom - (ChildWin\bottom - ChildWin\top) State=1 EndIf If State=1 ;GetCursorPos_(@Mouse) ;mouse_event_(#MOUSEEVENTF_ABSOLUTE | #MOUSEEVENTF_LEFTUP, Mouse\x, Mouse\y,0,0) SetWindowPos_(hwnd, #HWND_TOP, NewPosWin\x, NewPosWin\y, 0, 0, #SWP_NOSIZE) msg = 0 ;Debug "Блокирование перемещения окна" EndIf EndIf ProcedureReturn CallWindowProc_(*PointOldWinFunc,hwnd, msg, wParam, lParam) EndProcedure OpenWindow(0, 0, 0, 800, 600, "", #PB_Window_ScreenCentered) OpenWindow(1, 0, 0, 80, 60, "",#PB_Window_WindowCentered, WindowID(0)) *PointOldWinFunc = GetWindowLongPtr_(WindowID(1), #GWL_WNDPROC) SetWindowLongPtr_(WindowID(1), #GWL_WNDPROC, @WinProc() ) Repeat Event=WaitWindowEvent() Until Event=#PB_Event_CloseWindow
Поделиться1408.07.2013 11:27:28
Зачем же все так усложнять?
OpenWindow(0, 0, 0, 800, 600, "", #PB_Window_ScreenCentered) OpenWindow(1, 0, 0, 80, 60, "",#PB_Window_WindowCentered, WindowID(0)) SetParent_(WindowID(1), WindowID(0)) Repeat Event=WaitWindowEvent() Until Event=#PB_Event_CloseWindow
Поделиться1508.07.2013 18:04:25
А зачем 2 раза делать окно дочерним (первый раз при открытии, второй раз при юзании SetParent_()) ?
Поделиться1627.07.2013 22:26:28
Пётр
OpenWindow(0, 0, 0, 800, 600, "Главное окно",#PB_Window_Invisible | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered) OpenWindow(1, 0, 0, 280, 60, "Дочернее окно",#PB_Window_Invisible | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget, WindowID(0)) SetParent_(WindowID(1), WindowID(0)) HideWindow(0,0) HideWindow(1,0) Repeat Event=WaitWindowEvent() Until Event=#PB_Event_CloseWindow
Почему дочерное окно, принимает отступ с верху и отступ с лева, главного окна при растягивании дочерного окна?
Поделиться1720.08.2013 15:39:17
Пётр
Ну очень надо.
Отредактировано mestnyi (20.08.2013 17:58:44)
Поделиться1820.08.2013 19:51:46
Имеется в виду этот код?
Поделиться1921.08.2013 09:36:20
Пётр
Да.
Поделиться2021.08.2013 10:53:55
На WinAPI такое поведение не наблюдается.
Procedure WindowCallback(hWnd, Msg, wParam, lParam) Select Msg Case #WM_CLOSE DestroyWindow_(hWnd) Case #WM_DESTROY PostQuitMessage_(0) : Result = 0 Default Result = DefWindowProc_(hWnd, Msg, wParam, lParam) EndSelect ProcedureReturn Result EndProcedure Procedure Win(Class.s, Win) wc.WNDCLASSEX wc\cbsize = SizeOf(WNDCLASSEX) wc\lpfnWndProc = @WindowCallback() wc\hCursor = LoadCursor_(0, #IDC_ARROW) wc\hbrBackground = #COLOR_WINDOW wc\lpszClassName = @Class RegisterClassEx_(@wc) ProcedureReturn CreateWindowEx_(0, Class, "", #WS_VISIBLE|#WS_SYSMENU | #WS_MINIMIZEBOX|#WS_MAXIMIZEBOX|#WS_SIZEBOX, 0, 0, 200, 120, Win,0, 0, 0) EndProcedure hWnd=Win("Win1", 0) w=Win("Win1", hWnd) SetParent_(w, hWnd) While GetMessage_(msg.MSG, #Null, 0, 0) TranslateMessage_(msg) DispatchMessage_(msg) Wend
Значит это одна из корректировок в PB либе. Можешь написать на официальном форуме. Возможно подскажут что делать.
Поделиться2122.08.2013 11:10:48
Пётр
Я там не смог регистрацию сделать, можешь поможешь?
Поделиться2222.08.2013 11:20:03
Case #WM_SIZE RedrawWindow_(w, 0, 0, #RDW_ALLCHILDREN|#RDW_UPDATENOW) ; Уменьшаем мерцания окна с помошью Api при изменении его размеров.
Почему не действует? Имеется в виду не убирает мерцание, везде работало же.
Поделиться2322.08.2013 13:16:10
Я там не смог регистрацию сделать, можешь поможешь?
Где? На http://forums.purebasic.com?
Мыло какое использовал при регистрации? Лучше всего от гугла. как зарегится на оф сайте?
Почему не действует?
SmartWindowRefresh() есть в коде?
Поделиться2422.08.2013 15:05:01
Пётр
SmartWindowRefresh() есть в коде?
это ерунда она почти не помогает, а вот
RedrawWindow_(w, 0, 0, #RDW_ALLCHILDREN|#RDW_UPDATENOW)
чётко срабативает даже с гаджетамы .
вот handle - w -дочерного окна получаю 0, почему?
SetParent_(w, hWnd) убирает стиль дочерного окна, возможно ли этому помешать.
Поделиться2522.08.2013 16:24:46
вот handle - w -дочерного окна получаю 0, почему?
Потому что что-то неправильно делаешь. Без кода больше нечего добавить.
SetParent_(w, hWnd) убирает стиль дочерного окна
Какой именно стиль?
Поделиться2622.08.2013 17:34:32
Без кода больше нечего добавить.
вот
Declare WindowCallback(hWnd, Msg, wParam, lParam) Procedure WinChild(Class.s, x, y, width, height,Caption$,Win) wc.WNDCLASSEX wc\cbsize = SizeOf(WNDCLASSEX) wc\lpfnWndProc = @WindowCallback() wc\hCursor = LoadCursor_(0, #IDC_ARROW) wc\hbrBackground = #COLOR_WINDOW wc\lpszClassName = @Class RegisterClassEx_(@wc) ProcedureReturn CreateWindowEx_(0, Class, Caption$, #WS_VISIBLE|#WS_SYSMENU | #WS_MINIMIZEBOX|#WS_MAXIMIZEBOX|#WS_SIZEBOX, x, y, width, height, Win,0, 0, 0) EndProcedure Procedure WinMain(Class.s, x, y, width, height,Caption$, Win) wc.WNDCLASSEX wc\cbsize = SizeOf(WNDCLASSEX) wc\lpfnWndProc = @WindowCallback() wc\hCursor = LoadCursor_(0, #IDC_ARROW) wc\hbrBackground = #COLOR_WINDOW wc\lpszClassName = @Class RegisterClassEx_(@wc) ProcedureReturn CreateWindowEx_(0, Class, Caption$, #WS_VISIBLE|#WS_SYSMENU | #WS_MINIMIZEBOX|#WS_MAXIMIZEBOX|#WS_SIZEBOX, x, y, width, height, Win,0, 0, 0) EndProcedure hWnd=WinMain("Win1", 0, 0, 800, 600,"Средствами WinAPI - "+Chr(34)+" Главное окно "+Chr(34), 0) w=WinChild("Win2", 0, 0, 280, 60, "Дочернее окно", hWnd) SetParent_(w, hWnd) While GetMessage_(msg.MSG, #Null, 0, 0) TranslateMessage_(msg) DispatchMessage_(msg) Wend Procedure WindowCallback(hWnd, Msg, wParam, lParam) Select Msg Case #WM_CLOSE DestroyWindow_(hWnd) Case #WM_DESTROY PostQuitMessage_(0) : Result = 0 Case #WM_SIZE Debug w RedrawWindow_(w, 0, 0, #RDW_ALLCHILDREN|#RDW_UPDATENOW) ; Уменьшаем мерцания окна с помошью Api при изменении его размеров. Default Result = DefWindowProc_(hWnd, Msg, wParam, lParam) EndSelect ProcedureReturn Result EndProcedure
Поделиться2722.08.2013 17:36:22
Какой именно стиль?
не знаю, но вид меняться на win8.
Поделиться2822.08.2013 18:43:09
w -дочерного окна получаю 0, почему?
Потому что область видимости переменной w ограничивается глобальной областью. У процедур своя (локальная) область видимости.
Об этом написано здесь. http://pure-basic.narod.ru/docs/books/6.htm
Нужно переменную w сделать глобальной. Но в этом смысла нет, т. к. в аргументе hWnd будет хендл текущего окна. Замени в RedrawWindow, переменную w на hWnd.
вид меняться на win8
На XP стили не меняются.
Поделиться2922.08.2013 21:15:06
Пётр только так получается правильно получит handle обоих окон, мерцание не уходит.
Declare WinMainCallback(hWnd, Msg, wParam, lParam) Declare WinChildCallback(hWnd, Msg, wParam, lParam) Procedure WinMain(Class.s, x, y, width, height,Caption$, Win) wc.WNDCLASSEX wc\cbsize = SizeOf(WNDCLASSEX) wc\lpfnWndProc = @WinMainCallback() wc\hCursor = LoadCursor_(0, #IDC_ARROW) wc\hbrBackground = #COLOR_WINDOW wc\lpszClassName = @Class RegisterClassEx_(@wc) ProcedureReturn CreateWindowEx_(0, Class, Caption$, #WS_VISIBLE|#WS_SYSMENU | #WS_MINIMIZEBOX|#WS_MAXIMIZEBOX|#WS_SIZEBOX, x, y, width, height, Win,0, 0, 0) EndProcedure Procedure WinChild(Class.s, x, y, width, height,Caption$,Win) wc.WNDCLASSEX wc\cbsize = SizeOf(WNDCLASSEX) wc\lpfnWndProc = @WinChildCallback() wc\hCursor = LoadCursor_(0, #IDC_ARROW) wc\hbrBackground = #COLOR_WINDOW wc\lpszClassName = @Class RegisterClassEx_(@wc) ProcedureReturn CreateWindowEx_(0, Class, Caption$, #WS_VISIBLE|#WS_SYSMENU | #WS_MINIMIZEBOX|#WS_MAXIMIZEBOX|#WS_SIZEBOX, x, y, width, height, Win,0, 0, 0) EndProcedure hWnd1=WinMain("Win1", 0, 0, 800, 600,"Средствами WinAPI - "+Chr(34)+" Главное окно "+Chr(34), 0) hWnd=WinChild("Win2", 0, 0, 280, 60, "Дочернее окно", hWnd1) SetParent_(hWnd, hWnd1) While GetMessage_(msg.MSG, #Null, 0, 0) TranslateMessage_(msg) DispatchMessage_(msg) Wend Procedure WinMainCallback(hWnd, Msg, wParam, lParam) Select Msg Case #WM_CLOSE DestroyWindow_(hWnd) Case #WM_DESTROY PostQuitMessage_(0) : Result = 0 Case #WM_SIZE Debug hWnd RedrawWindow_(hWnd, 0, 0, #RDW_UPDATENOW|#RDW_UPDATENOW) ; Уменьшаем мерцания окна с помошью Api при изменении его размеров. Default Result = DefWindowProc_(hWnd, Msg, wParam, lParam) EndSelect ProcedureReturn Result EndProcedure Procedure WinChildCallback(hWnd, Msg, wParam, lParam) Select Msg Case #WM_CLOSE DestroyWindow_(hWnd) Case #WM_DESTROY PostQuitMessage_(0) : Result = 0 Case #WM_SIZE Debug hWnd RedrawWindow_(hWnd, 0, 0, #RDW_UPDATENOW|#RDW_UPDATENOW) ; Уменьшаем мерцания окна с помошью Api при изменении его размеров. Default Result = DefWindowProc_(hWnd, Msg, wParam, lParam) EndSelect ProcedureReturn Result EndProcedure
Отредактировано mestnyi (22.08.2013 21:15:33)
Поделиться3022.08.2013 21:32:02
С handle не могу никак разобраться. Почему не работает?
Procedure hDrawPoints(hWnd) If LoadFont(1, "Arial", 8) If CreateImage(0, WindowWidth(WindowID(hWnd)), WindowHeight(WindowID(hWnd))) And StartDrawing(ImageOutput(0)) DrawingMode(#PB_2DDrawing_Transparent) Box(0, 0, WindowWidth(WindowID(hWnd)), WindowHeight(WindowID(hWnd)), RGB(245,245,245)) For i = 8 To (WindowWidth(WindowID(hWnd))) Step 10 DrawingFont(FontID(1)) DrawText( i,-2, ".", RGB(55, 55, 55)) For j = 8 To (WindowHeight(WindowID(hWnd))) Step 10 DrawingFont(FontID(1)) DrawText( i,j, ".", RGB(55, 55, 55)) Next Next StopDrawing() ImageGadget(#PB_Any, 0, 0, 200, 200, ImageID(0)) EndIf EndIf EndProcedure Procedure WinChildCallback(hWnd, Msg, wParam, lParam) Select Msg Case #WM_CLOSE DestroyWindow_(hWnd) Case #WM_DESTROY PostQuitMessage_(0) : Result = 0 Case #WM_SIZE hDrawPoints(hWnd) Default Result = DefWindowProc_(hWnd, Msg, wParam, lParam) EndSelect ProcedureReturn Result EndProcedure Procedure WinChild(Class.s, x, y, width, height,Caption$,Win) wc.WNDCLASSEX wc\cbsize = SizeOf(WNDCLASSEX) wc\lpfnWndProc = @WinChildCallback() wc\hCursor = LoadCursor_(0, #IDC_ARROW) wc\hbrBackground = #COLOR_WINDOW wc\lpszClassName = @Class RegisterClassEx_(@wc) ProcedureReturn CreateWindowEx_(0, Class, Caption$, #WS_VISIBLE|#WS_SYSMENU | #WS_MINIMIZEBOX|#WS_MAXIMIZEBOX|#WS_SIZEBOX, x, y, width, height, Win,0, 0, 0) EndProcedure hWnd1=WinChild("Win2", 0, 0, 480, 220, "Дочернее окно", hWnd) While GetMessage_(msg.MSG, #Null, 0, 0) TranslateMessage_(msg) DispatchMessage_(msg) Wend