PureBasic - форум

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

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


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


Вопросы новичка

Сообщений 871 страница 900 из 1000

871

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

И еще, можно ли внутри одной процедуры запускать другую??

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

Код:
Procedure Udav()
  Udav()
EndProcedure

Udav()

Другими словами, произошло переполнение стека

0

872

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

Другую можно, а вот саму себя не желательно, хотя допустимо.

Да я сам тормознул, вызвал процедуру до ее описания, в результате ошибка,-  не известная процедура. Сразу почему-то не сообразил что к чему… (переклинило) :D

А почему delay() в предыдущей схеме не корректно использовать…?

Отредактировано Lucagin (10.12.2010 16:43:46)

0

873

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

А почему delay() в предыдущей схеме не корректно использовать…?

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

0

874

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

Потому что в этом случае, не обрабатываются системные сообщения, которые посылает система в окно.

вот значит как, теперь понятно... :idea:

Отредактировано Lucagin (10.12.2010 17:40:19)

0

875

Ребят, поясните, по возможности развернуто, применение   WaitWindowEvent(5) в этой процедуре? Справку посмотрел, но ясности не прибавилось… 5 Мсек здесь берется произвольно  или это чем-то обосновано?

ВиниПур написал(а):

Procedure Wait(ms)
ms+ElapsedMilliseconds()
Repeat
WaitWindowEvent(5)
Until ElapsedMilliseconds()>ms
EndProcedure

0

876

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

то код один раз сработает

Код:
Enumeration
  #Window_0
EndEnumeration
Enumeration
  #Text_0
  #Button_0
  #Button_1
EndEnumeration
Global FontID1
FontID1 = LoadFont(1, "Arial", 36)
Global FontID2
FontID2 = LoadFont(2, "Arial", 28)

Procedure Open_Window_0()
  If OpenWindow(#Window_0, 381, 168, 730, 400, "New window ( 0 )",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
      TextGadget(#Text_0, 160, 100, 420, 60, "ОБРАЗЕЦ!!!", #PB_Text_Center)
      SetGadgetFont(#Text_0, FontID1)
      ButtonGadget(#Button_0, 40, 290, 230, 60, "Верно")
      SetGadgetFont(#Button_0, FontID2)
      ButtonGadget(#Button_1, 460, 290, 230, 60, "Не верно")
      SetGadgetFont(#Button_1, FontID2) 
  EndIf
  HideGadget(#Text_0, 1)
EndProcedure


Open_Window_0()

Repeat
  Event=WaitWindowEvent()
  Gadget=EventGadget()
  If Event=#PB_Event_Gadget 
    If gadget=#Button_0
        HideGadget(#Text_0, 0)
        SetGadgetColor(#Text_0, #PB_Gadget_FrontColor, RGB(98, 200, 103))
        SetGadgetText(#Text_0, "Верно")
        Delay(500)
        HideGadget(#Text_0, 1)
      Else
        HideGadget(#Text_0, 0)
        SetGadgetColor(#Text_0, #PB_Gadget_FrontColor, RGB(255, 0, 0))
        SetGadgetText(#Text_0, " Не Верно")
        Delay(500)
        HideGadget(#Text_0, 1)  
   EndIf   
EndIf

HideGadget(#Text_0, 0) не в том месте...

0

877

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

HideGadget(#Text_0, 0) не в том месте...

Я хоте в начале изменить надпись, а потом сделать её видимой,  думал, что в твоем варианте появится надпись “ОБРАЗЕЦ!!!” а потом  изменится на заданную… Но вижу работает правильно… :о)

Однако странно, почему Delay() блокирует изменение видимости окна, но смену надписи не блокирует???  Ведь  “в этом случае, не обрабатываются системные сообщения, которые посылает система в окно”.

Отредактировано Lucagin (10.12.2010 19:12:16)

0

878

На время работы Delay(500) программа всегда зависает, если малые промежутки, то можно пренебречь и упростить код.

на большие не корректно

Отредактировано mirashic (10.12.2010 19:05:42)

0

879

Все правильно работает

сделали надпись видимой
изменили текст и шрифт
  - это всё мгновенно

пауза Delay(500)
скрыли текст

0

880

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

На время работы Delay(500) программа всегда зависает, если малые промежутки, то можно пренебречь и упростить код.

А почему тогда вариант исходный не проходит, если на малых задержках можно использовать? Вероятно, смена текста в гаджете происходит "быстрее", чем гашение гаджета...?

Отредактировано Lucagin (10.12.2010 19:22:22)

0

881

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

Все правильно работает

сделали надпись видимой
изменили текст и шрифт
  - это всё мгновенно

В любом случае спасибо, сам бы переставить не додумался, в силу стереотипа:  “В начале меняем, потом показываем”  :nope:  :yep:  ;)

Отредактировано Lucagin (10.12.2010 19:48:13)

0

882

В твоём первом варианте работает так

запустили программу
скрыли текст

главный цикл

нажали на кнопку
изменили текст и шрифт - а окно не перерисовали
разрешили показать но нечего
пауза
скрыли

закончили цикл

я так понимаю

0

883

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

разрешили показать но нечего

Вобщем да, надо было вообще отказаться от HideGadget(#Text_0, 1) а просто менять текст надписи... или на нужную  или  на пустую...

Отредактировано Lucagin (10.12.2010 19:55:12)

0

884

Ребят, а подскажите,  как изменить размер шрифта в меню???

Отредактировано Lucagin (10.12.2010 23:11:40)

0

885

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

Ребят, а подскажите,  как изменить размер шрифта в меню???

Стандартными средствами вроде никак.
Можно использовать библиотеку XP_Menu_Lib, которую можно скачать здесь http://pure-basic.narod.ru/libs.html
Она кроме всего прочего, позволяет выбрать шрифт и его размер.

Код:
Procedure GlavWindowCallback(WindowID, Message, wParam, lParam)
Protected Result=#PB_ProcessPureBasicEvents
 XP_Menu_CB(WindowID, Message, wParam, lParam) ; Обработчик событий библиотеки  XP_Menu_Lib
ProcedureReturn Result 
EndProcedure

LoadFont(0,"Arial",20)

If OpenWindow(0, 200, 200, 200, 100, "Menu Example")
    SetWindowCallback(@GlavWindowCallback())
    If CreateMenu(0, WindowID(0))    ; menu creation starts....
      MenuTitle("Project")
        MenuItem(1, "Open"   +Chr(9)+"Ctrl+O")
        MenuItem(2, "Save"   +Chr(9)+"Ctrl+S")
        MenuItem(3, "Save as"+Chr(9)+"Ctrl+A")
        MenuItem(4, "Close"  +Chr(9)+"Ctrl+C")
        
        XP_MenuRegister(MenuID(0), #XP_RegMenu, #XP_RegGeneralMenu, WindowID(0)) ; Регистрация меню в библиотеке XP_Menu_Lib
        XP_SetMenuFont(FontID(0), #XP_FontItem)
        
    EndIf
    Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
  EndIf

0

886

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

Стандартными средствами вроде никак.Можно использовать библиотеку XP_Menu_Lib,

Хорошо, все равно этот модуль надо осваивать…Благо, справка там подробная…:о)

0

887

Обнаружил в PB систему символов, которая вызывает некие изменения в оформлении кода:
;- Gadget Constants   (в закладке процедуры, появляется метка констант гаджетов)
;{  ;}  (позволяет сворачивать часть кода подобно сворачиванию кода процедур.

Какие еще есть сочетания символов, облегчающих работу с кодом и где их можно посмотреть?

Отредактировано Lucagin (12.12.2010 19:00:12)

0

888

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

;{  ;}  (позволяет сворачивать часть кода подобно сворачиванию кода процедур.

Это заданно в настройках в разделе Редактор --> Сворачивание.

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

Какие еще есть сочетания символов, облегчающих работу с кодом и где их можно посмотреть?

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

0

889

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

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

Спасибо Пётр, теперь понятно! Я думал, сочетания символов зашито внутри программы, а оказывается их можно настраивать… :о) Авто завершение  у меня стоит по умолчанию (по 3-м символам)…

Здесь, оказывается, можно настроить сворачивание  условные операторы и циклов. Думал что это в PB не предусмотрено.  После алгоритма, отсутствие этих сворачивание было большим неудобством… На сколько, однако,  в PB всё продумано… :о))

Отредактировано Lucagin (12.12.2010 19:52:53)

0

890

А есть ли какие советы по отладке программ в PB. Смотрю в закладке "Отладчик" много пунктов, которые не активны… (результат отладки, наблюдение и др.) есть где-то справка, в которой описано,  как всем этим арсеналом грамотно пользоваться?

В принципе по логу событий в нижней части экрана и так понятно в чем ошибка или что происходит, но может есть какие-то секреты отладки, которые сразу стоит усвоить?

Отредактировано Lucagin (12.12.2010 20:27:38)

0

891

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

Смотрю в закладке Отладчик много пунктов, которые не активны…

Нужно запустить программу и тогда они станут активными.
Можно добавить точку остановки программы.
Для этого, ставим текстовый курсор, на интерисусщую строку и нажимает на кнопку F9. Слева от строки, появится точка (обычно желтого цвета).

http://s49.radikal.ru/i126/1012/bd/53c1900fb549.png

Следующее нажатие на кнопку F9, уберёт точку остановки со строки.
Как только выполнение программы дойдет до строки с точкой остановки - прорамма "заморозится" отладчиком и можно будет выполнять её в пошаговом режиме, нажимая на кнопку F8.
Так же можно узнать что хранится в какой переменной или массиве.
Для этого, нужно запустить программу и навести курсор мышки на интерисующую строку - появится всплывающее окно с текущим значением переменной.

http://i026.radikal.ru/1012/f4/6b162f837344.png

Более подробную информацию о данных в переменных, массивах, структурах, можно получить открыв окно отладчика с помощью меню "Отладчик" --> "Просмотр переменных".

http://i081.radikal.ru/1012/ff/5dda52a716b8.png

Открыв окно "Отладчик" --> "Профилирование", можно посмотреть какой код наиболее часто вызывается (напрмер, чтобы оптимизировать его для ускорения работы проги).

http://i081.radikal.ru/1012/4b/a5e7144c0928.png

В окне "Отладчик" --> "История вызовов", можно посмотреть какая процедура сколько раз вызываась.

http://s60.radikal.ru/i168/1012/b1/cca4bb46a714.png

0

892

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

Как только выполнение программы дойдет до строки с точкой остановки - прорамма "заморозится" отладчиком и можно будет выполнять её в пошаговом режиме, нажимая на кнопку F8.Так же можно узнать что хранится в какой переменной или массиве.Для этого, нужно запустить программу и навести курсор мышки на интерисующую строку - появится всплывающее окно с текущим значением переменной.

Спасибо, Пётр, очень ценная информация!!! Я думаю это существенно ускорит  отладку программ… Раньше использовал только debug () и логи событий…

Не думал, что столько полезного есть в отладчике!!! :cool:

Отредактировано Lucagin (12.12.2010 21:10:13)

0

893

Ребят помогите разобраться!!! Хочу, при нажатии на кнопку, изменить цвет рисунка, увеличив красный цвет на 5 единиц в схеме RGB(). Не могу понять, что происходит с шириной и высотой  ImageGadget(). Почему они меняются при вызове процедуры Zalivka() на +4 пикселя…??? Вернее, при первом запуске процедуры размеры гаджета не меняются. Вероятно, при вызове процедуры, надо уничтожать предварительно созданное изображение, но все равно не понятно, как это может влиять на размер гаджета!?

Код:
;{- Enumerations / DataSections
;{ Windows
Enumeration
  #Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
  #Button_0
  #Image_1
EndEnumeration
;}
;{ Fonts
Enumeration
  #Font_Button_0
EndEnumeration
;}
;{ Images
Enumeration
  #Image_Image_1
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 450, 200, 682, 499, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
     ButtonGadget(#Button_0, 190, 385, 250, 55, "Изменить цвет")
     ImageGadget(#Image_1, 85, 40, 500, 300, 0, #PB_Image_Border)
    ; Gadget Fonts
     SetGadgetFont(#Button_0, LoadFont(#Font_Button_0, "Microsoft Sans Serif", 24, 16))
  EndIf
EndProcedure

Procedure Zalivka (ID, R,G,B)
  
  W = GadgetWidth(ID)
  H = GadgetHeight(ID)
  Debug W
  Debug H
  
 If CreateImage(ID+10, W, H) And StartDrawing(ImageOutput(ID+10))
    Box(0, 0, W,H, RGB(R, G, B))
    StopDrawing() 
    
    SetGadgetState(ID, ImageID(ID+10))

 EndIf

EndProcedure



OpenWindow_Window_0()
Zalivka (#Image_1, 0,0,0)
HideWindow(#Window_0, 0) 

a=0

;{Основной цикл
Repeat
  Event = WaitWindowEvent()
  Gadget = EventGadget()
    
  If Event=#PB_Event_Gadget
    If Gadget=#Button_0
      a=a+5
      Zalivka (#Image_1, a,0,0)
     EndIf
  EndIf 
  
 Until Event=#PB_Event_CloseWindow
;}
End

Отредактировано Lucagin (13.12.2010 14:01:00)

0

894

А почему бы не измерять размер рисунка в место размера гаджета?

Код:
;{- Enumerations / DataSections
;{ Windows
Enumeration
  #Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
  #Button_0
  #Image_1
EndEnumeration
;}
;{ Fonts
Enumeration
  #Font_Button_0
EndEnumeration
;}
;{ Images
Enumeration
  #Image_Image_1
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 450, 200, 682, 499, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_Invisible)
     ButtonGadget(#Button_0, 190, 385, 250, 55, "Изменить цвет")
     ImageGadget(#Image_1, 85, 40, 500, 300, 0, #PB_Image_Border)
    ; Gadget Fonts
     SetGadgetFont(#Button_0, LoadFont(#Font_Button_0, "Microsoft Sans Serif", 24, 16))
  EndIf
EndProcedure

Procedure Zalivka (ID, R,G,B)
  If IsImage(ID+10) ; Существует ли рисунок с таким ID
    W = ImageWidth(ID+10)
    H = ImageHeight(ID+10)
  Else
    W = 500
    H = 300
  EndIf
  Debug W
  Debug H
  
 If CreateImage(ID+10, W, H) And StartDrawing(ImageOutput(ID+10))
    Box(0, 0, W,H, RGB(R, G, B))
    StopDrawing() 
    
    SetGadgetState(ID, ImageID(ID+10))

 EndIf

EndProcedure



OpenWindow_Window_0()
Zalivka (#Image_1, 0,0,0)
HideWindow(#Window_0, 0) 

a=0

;{Основной цикл
Repeat
  Event = WaitWindowEvent()
  Gadget = EventGadget()
    
  If Event=#PB_Event_Gadget
    If Gadget=#Button_0
      a=a+5
      Zalivka (#Image_1, a,0,0)
     EndIf
  EndIf 
  
 Until Event=#PB_Event_CloseWindow
;}
End

0

895

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

А почему бы не измерять размер рисунка в место размера гаджета?

Я хотел чтобы  процедура стала универсальной, и чтобы она  могла менять цвет в ImageGadget() любого размера, предварительно измерив его размер. Т.е. W and H каждый раз разные…
А почему в моем случае не работает?

0

896

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

чтобы она  могла менять цвет в ImageGadget() любого размера, предварительно измерив его размер

Цвет будет изменятся все равно в рисунке, поэтому лучше измерять размер рисунка.

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

А почему в моем случае не работает?

Потому что размер ImageGadget не обязательно равен рисунку.
И кроме того, в данном случае, не обязательно каждый раз создавать рисунок по новой, достаточно создать его один раз в начале программы.

0

897

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

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

Я понимаю, что создавать каждый раз изображение не нужно, просто не до конца уяснил, при
такой прорисовке созданного изображения, “старый” квадрат полностью заменяется новым,  это аналогично смене цвета у шрифта? Старый квадрат при этом отдельно стирать перед прорисовкой не надо, дабы избежать потерь памяти?
Память занимает только само изображение, или и  то, что на нем нарисовано?

Код:
StartDrawing(ImageOutput(ID+10))
      Box(0, 0, W,H, RGB(R, G, B))
StopDrawing()

Отредактировано Lucagin (13.12.2010 14:49:04)

0

898

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

просто не до конца уяснил, при такой прорисовке созданного изображения, “старый” квадрат полностью заменяется новым

В нашем случае, функция Box полностью стирает предыдущее изображение, потому как аргументы x и y равны 0, т. е. начальной координате рисунка, а аргументы Width и Height размеру изображения.

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

Старый квадрат при этом отдельно стирать перед прорисовкой не надо, дабы избежать потерь памяти?

Так он же стирается функцией Box. Потери памяти при это нет.

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

Память занимает только само изображение, или и  то, что на нем нарисовано?

Память выделяется под изображение и её объём зависит от размера изображения - чем больше размеры, тем больше требуется памяти.

Вот вариант с однократным созданием рисунка

Код:
;{- Enumerations / DataSections
;{ Windows
Enumeration
  #Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
  #Button_0
  #Image_1
EndEnumeration
;}
;{ Fonts
Enumeration
  #Font_Button_0
EndEnumeration
;}
;{ Images
Enumeration
  #Image_Image_1
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 450, 200, 682, 499, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_Invisible)
     ButtonGadget(#Button_0, 190, 385, 250, 55, "Изменить цвет")
     CreateImage(#Image_1, 500, 300)
     ImageGadget(#Image_1, 85, 40, 500, 300, 0, #PB_Image_Border)
    ; Gadget Fonts
     SetGadgetFont(#Button_0, LoadFont(#Font_Button_0, "Microsoft Sans Serif", 24, 16))
  EndIf
EndProcedure

Procedure Zalivka (ID, R,G,B)
  If IsImage(ID) ; Существует ли рисунок с таким ID
    W = ImageWidth(ID)
    H = ImageHeight(ID)
    Debug W
    Debug H
    If StartDrawing(ImageOutput(ID))
      Box(0, 0, W,H, RGB(R, G, B))
      StopDrawing() 
      SetGadgetState(ID, ImageID(ID))
    EndIf
  EndIf
EndProcedure



OpenWindow_Window_0()
Zalivka (#Image_1, 0,0,0)
HideWindow(#Window_0, 0) 

a=0

;{Основной цикл
Repeat
  Event = WaitWindowEvent()
  Gadget = EventGadget()
    
  If Event=#PB_Event_Gadget
    If Gadget=#Button_0
      a=a+5
      Zalivka (#Image_1, a,0,0)
     EndIf
  EndIf 
  
 Until Event=#PB_Event_CloseWindow
;}
End

0

899

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

Так он же стирается функцией Box. Потери памяти при это нет.

Спасибо, Пётр!!! Теперь всё понятно !!! Просто не был уверен, что Box () и др. команды 2D-рисования предварительно стирают пространство, на котором будут рисовать…   :cool:

Отредактировано Lucagin (13.12.2010 15:07:23)

0

900

Хочу, чтобы на экране были разбросаны с десяток простеньких элементов (прямая, квадрат, линия, круг, может объекты более сложной формы) разных цветов. При этом должна быть возможность кликнуть по этим простеньким элементам, с их какой-либо модификацией (исчезли, поменяли цвет и т.п.) Как лучше осуществить этот проект с помощью использования ImageGadget() или можно использовать CreateSprite(). Будет ли выигрышь при использовнаии Sprite и позволят ли они полностью функционально заменить   ImageGadget() (возможность кликать по ним и работа в обычном окне)?
Или спрайты лучше использовать только для игр? Посмотрел в справке, для их использования  надо DirectX, это наверно уже лишний навес,  для такой простой задачи?

Отредактировано Lucagin (13.12.2010 21:10:41)

0


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