PureBasic - форум

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

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


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


Вопросы новичка (продолжение…)

Сообщений 511 страница 540 из 961

511

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

в чём может быть проблема

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

0

512

Пётр, врядли дело в этом, такая ситуация (все потоки ждут сообщения и не пишут возможна), но ведь там в определённый момент эта ситуация начинается и не заканчиваться. Не дело же в рандоме, не может же он после определённого момента выдаватькаждый раз одинаковое значение (0 - принять, 1 - отправить), может дело в семафоре и мьютексе, но как их тогда использовать?

0

513

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

может дело в семафоре и мьютексе, но как их тогда использовать?

Вот и я о том же.
Скорее всего потоки блокируются семафором потому что ждут приема команд, а не передают их.
http://ru.wikipedia.org/wiki/Взаимная_блокировка

0

514

Без семафора не зависает.
По моему он вообще не нужен в рассматриваемом случае.

0

515

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

Код:
Global true.b = 1                                  ; переменная для вычного цикла
Global mutex = CreateMutex()                       ; объявление мьютекса    

Structure messagebox
  sender.l                                          ; номер потока, который отправляет сообщение
  recipient.l                                       ; номер потока, которому нужно отпарвить сообщение
  message_body.s                                    ; само сообщение
EndStructure
 
Global NewList queue.messagebox()                 ; объявление списка queue, в который записываются сообщения 

Procedure send(sender_thread.l, recipient_thread.l, message.s)
  
  ; send - посылает сообщение заданному потоку
  ; sender_thread - какой поток отсылает сообщение
  ; recipient_thread - какому потоку отослать сообщение
  ; message - само сообщение

  LastElement(queue())                              ; переходим к последнему элементу в списке
  AddElement(queue())                               ; добавить новый элемент в список
   
  queue()\sender = sender_thread                    ; пишем какой поток хочет отослать
  queue()\recipient = recipient_thread              ; пишем какому потоку хотим отправить сообщение
  queue()\message_body = message                    ; само сообщение
EndProcedure

Procedure.s receive(recipient_message.l)
  
  ; receive - получет сообщение от другого потока
  ; recipient_message - номер потока, который хочет получить сообщение

  message.s = ""                                    ; переменная для записи всех сообщений, которые пришли данному потоку
  
  ForEach queue()                                  ; перебираем все сообщения в списке
    
    If queue()\recipient = recipient_message        ; если это сообщение направлено данному потоку
                                                    ; записываем сообщение (далее - все сообщения, которые были отосланы этому потоку)
      message = message + "поток " + Str(recipient_message) + " принял: " + queue()\message_body + " от потока " + Str(queue()\sender) + "; "  
      DeleteElement(queue())                        ; Удаление текущего сообщения из списка
    EndIf
    
  Next
  
  ProcedureReturn message.s  
EndProcedure

Procedure Thread(*number)                           ; код отдельного потока (всего их 4)
  
  counter.i = 0                                      ; переменная для данных (их отображение) 
  While true = 1 
    Delay(1000)
    
    send_of_receive.l = Random(1)                    ; поток узнаёт, отправить ли сообщение (1), или принять (0)

    If send_of_receive = 1                           ; если 1, значит отослать
      
      LockMutex(mutex)                               ; входим в критическую секцию, с помощью мьютекса
      
      While true = 1                                ; в цикле поток узнаёт, какому потоку отправить сообщение
        send_thread.l = Random(3)                    ; но поток не может послать сам себе сообщение
        If Not send_thread = *number
          Break
        EndIf
      Wend    

      data_message.s = "message" + Str(counter)      ; формируем сообщение для отправки
      counter = counter + 1                          ; увеличиваем значение переменной, чтобы различать сообщения

      send(*number, send_thread.l, data_message.s)   ; отправить сообщение указанному потоку
      
      UnlockMutex(mutex)                             ; выходим из критической секции, с помощью мьютекса
    Else                                             ; иначе получаем сообщение
      
      LockMutex(mutex)                               ; входим в критическую секцию, с помощью мьютекса
      
      received_message.s = receive(*number)          ; получаем сообщения
      
      If Not received_message = ""                   ; если этому потоку ни кто сообщения не посылал, то ничего и не выводим
         Debug received_message
      EndIf
      
      UnlockMutex(mutex)                             ; выходим из критической секции, с помощью мьютекса  
    EndIf
  Wend 
EndProcedure

thread0 = CreateThread(@Thread(), 0)   ; создать поток thread0
thread1 = CreateThread(@Thread(), 1)   ; создать поток thread1
thread2 = CreateThread(@Thread(), 2)   ; создать поток thread2
thread3 = CreateThread(@Thread(), 3)   ; создать поток thread3

  
WaitThread(thread0)      
WaitThread(thread1)
WaitThread(thread2)
WaitThread(thread3)

А вот какой вариант предпочтительнее, как здесь, потоки пишут, затем один поток считывает все пришедшие к нему сообщения, или же мол поток отсылает сообщение и передаёт после передачи управление потоку получателю (чтобы он его сразу принял)? Да и можно ли передать управление заданному потоку?

Отредактировано goodwen (26.05.2011 16:47:58)

0

516

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

Да и можно ли передать управление заданному потоку?

Они ведь работают независимо друг от друга, разве что останавливать и запускать мьютексами.
Но в данном случае, и так работает.

0

517

Пётр, спасибо за помощь.

0

518

Приветствую ВАС!
Пожалуйста, помогите понять. Я собрал из 3-х LineXY(x1,y1,x2,y2,Color)
треугольник. Хочу заполнить цветом.
Как пользоваться функцией FillArea(x, y, OutlineColor[,FillColor]).
                         С уважением,   Akiva

0

519

Всем привет!
Есть рабочая прога. За загрузку иконки отвечает строчка:

Код:
AddSysTrayIcon(25, WindowID(#Window_0), ExtractIcon_(0,ProgramFilename(),0))

Вопрос в следующем: в папке с программой поменял иконку с другим именем, при компеляции не может ее найти.
Переименовываю ее, все нормально. Не подскажите в чем проблема? Не хочется ее переименовывать.
Заранее спасибо!

0

520

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

треугольник. Хочу заполнить цветом.Как пользоваться функцией FillArea

Нужно в x и y указать координаты, лежащие внутри треугольника.

Код:
If OpenWindow(0, 0, 0, 200, 200, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If CreateImage(0, 200, 200) And StartDrawing(ImageOutput(0))
      Box(0, 0, 200, 200, RGB(255, 255, 255))
      LineXY(20, 150, 100, 10, 0)
      LineXY(180, 150, 100, 10, 0)
      LineXY(20, 150, 180, 150, 0)
      
      FillArea(30, 140, -1 , RGB(254, 0, 0))

      StopDrawing() 
      ImageGadget(0, 0, 0, 200, 200, ImageID(0))
    EndIf
    
    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow
  EndIf

0

521

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

Есть рабочая прога. За загрузку иконки отвечает строчка:

В данном случае, используется иконка исполняемого файла.
Она заменяется в свойствах проекта в поле "Использовать иконку".

увеличить

0

522

Пётр, спасибо! Оно самое.

0

523

Не подскажете как определить объем диска С? Не свободную память, а общий объем! Заранее спасибо!

0

524

Дмитрий написал(а):

Не свободную память, а общий объем!

Какая разница? Определяется одинаково, только выбирай информацию, которая нужна:

Код:
Define.q free_bytes_avail, total_bytes, total_free_bytes

If (GetDiskFreeSpaceEx_("C:", @free_bytes_avail, @total_bytes, @total_free_bytes))
   Debug "Общий размер в байтах " + Str(total_bytes >> 20*1024)
EndIf

Отредактировано ВиниПур (31.05.2011 06:07:22)

0

525

Всем привет!
Можно ли как-то сделать многовкладочное меню, как на картинке у Петра в 521 посту?
Спасибо.

Отредактировано max (31.05.2011 09:36:28)

0

526

max
Пример из справки

Код:
  If OpenWindow(0, 0, 0, 322, 220, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    PanelGadget     (0, 8, 8, 306, 203)
      AddGadgetItem (0, -1, "Panel 1")
        PanelGadget (1, 5, 5, 290, 166)
          AddGadgetItem(1, -1, "Sub-Panel 1")
          AddGadgetItem(1, -1, "Sub-Panel 2")
          AddGadgetItem(1, -1, "Sub-Panel 3")
        CloseGadgetList()
      AddGadgetItem (0, -1,"Panel 2")
        ButtonGadget(2, 10, 15, 80, 24,"Button 1")
        ButtonGadget(3, 95, 15, 80, 24,"Button 2")
    CloseGadgetList()
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  EndIf

0

527

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

Пример из справки

Спасибо! Однако справку надо внимательней смотреть.

0

528

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

0

529

Спасибо, Петр
Но я так и не понял как определять координаты
лежащие внутри треугольника.
          С уважением к Вам. Akiva

0

530

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

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

Как вариант

Код:
 If OpenWindow(0, 0, 0, 100, 100, "Timer Example", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    TextGadget(0, 30, 30, 80, 20, "")
    AddWindowTimer(0, 123, 1000)
    
    Value = 0
    Repeat
      Event = WaitWindowEvent()
      
      If Event = #PB_Event_Timer And EventTimer() = 123
        SetGadgetText(0,FormatDate("%hh:%ii:%ss", Date()))
      EndIf    
      
    Until Event = #PB_Event_CloseWindow
  EndIf
Akiva написал(а):

Но я так и не понял как определять координатылежащие внутри треугольника.

Просто нужно найти точку, лежащую внутри треугольника.
Например, нижняя горизонтальная линия треугольника, находится по игреку в позиции 150 и если найти центр этой линии (в нашем случае это 80 потому что 180 - 20 = 160/2 = 80) и подняться на несколько пикселей вверх этой линии (например 10, тогда позиция будет 150-10=140), то гарантировано будет точка, лежащая внутри треугольника.

Код:
If OpenWindow(0, 0, 0, 200, 200, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If CreateImage(0, 200, 200) And StartDrawing(ImageOutput(0))
    Box(0, 0, 200, 200, RGB(255, 255, 255))
    LineXY(20, 150, 100, 10, 0)
    LineXY(180, 150, 100, 10, 0)
    LineXY(20, 150, 180, 150, 0)  ; Нижняя горизонтальная линия
    
    FillArea(80, 140, -1 , RGB(254, 0, 0))
    
    StopDrawing() 
    ImageGadget(0, 0, 0, 200, 200, ImageID(0))
  EndIf
  
  Repeat
    Event = WaitWindowEvent()
  Until Event = #PB_Event_CloseWindow
EndIf

0

531

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

Как вариант

Спасибо!

0

532

Привет!
Как с помощью библиотеки Droopy или непосредственной работой с реестром удалить программу из автозагрузки?

0

533

Нашел.

Код:
RunProgramAtStartup(1,1,"Abracadabra","c:\windows\regedit.exe") ; Add to Startup
DelProgramAtStartup(1,1,"Abracadabra") ; Remove from Startup

0

534

Помнится кто то на нашем форуме хорошо ладил с Delphi. На форуме журнала ПРОграммист наткнулся на интереснейшую тему о определении температуры винта!!! Кто может перекатать на пурик!?!?Вот ссылка

0

535

Где-то я видел исходник проги, измеряющий температуру винта, но и где....
Да и давно это было, если найду, выложу.

0

536

Привет!
Возникло пару вопросов.
1.  Как загрузить текст из директории программы в EditorGadget.
2.  Как загрузить текст из любой папки на компе в EditorGadget.
Накидал код и застопорился. Код прилагается.

Код:
Global Text.s

OpenWindow(0, 0, 0, 350, 160, "122", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget)

PanelGadget (0, 5, 5, 340, 150)
AddGadgetItem (0, -1, "1")

AddGadgetItem (0, -1,"2")
 
AddGadgetItem (0, -1,"3")

AddGadgetItem (0, -1,"4")

AddGadgetItem (0, -1,"5")
     
AddGadgetItem (0, -1,"Текст")

ComboBoxGadget(48, 154, 98, 163, 21)

EditorGadget(49,154,7,163,89,#PB_Editor_ReadOnly)   

ButtonGadget(50,6,6,144,23,"Загрузить текст")

;Получает полный путь запущенного приложения      
Result$ = ProgramFilename()
;Извлекает путь из полного пути. Например, если полный путь "C:\PureBasic\PB.exe", результат будет "C:\PureBasic\". 
Path$ = GetPathPart(Result$)
;Debug Path$
; Просмотр всех элементов директории запущенного приложения  (без поддиректорий)
Directory$ = Path$   
  If ExamineDirectory(0, Directory$, "*.txt")  
  m=0
    While NextDirectoryEntry(0)

      AddGadgetItem(48, -1, Left(DirectoryEntryName(0), Len(DirectoryEntryName(0))-4))
      
      txt.s=Text + ".txt"
      
      If DirectoryEntryName(0) = txt
      SetGadgetState(48, m) 
      EndIf
     m=m+1      ;Debug DirectoryEntryName(0) ;+ Type$ + "- Size in byte: " + Str(DirectoryEntrySize(0))
    Wend
    FinishDirectory(0)
  EndIf

CloseGadgetList()

Repeat 
  
Event= WaitWindowEvent() 
Window=EventWindow() 
Gadget=EventGadget()

If Event=#PB_Event_Gadget
  
  Select EventGadget()
      
     Case 50
       
StandardFile$ = ""   ; set initial file+path to display
  ; With next string we will set the search patterns ("|" as separator) for file displaying:
  ;  1st: "Text (*.txt)" as name, ".txt" and ".bat" as allowed extension
  ;  2nd: "PureBasic (*.pb)" as name, ".pb" as allowed extension
  ;  3rd: "All files (*.*) as name, "*.*" as allowed extension, valid for all files
  Pattern$ = "Text (*.txt)|*.txt"
  Pattern = 0    ; use the first of the three possible patterns as standard
  File$ = OpenFileRequester("Открыть файл", StandardFile$, Pattern$, Pattern)
  If File$
    Debug File$
  EndIf
                                     
EndSelect 

EndIf 

Until WaitWindowEvent() = #PB_Event_CloseWindow

0

537

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

Привет!Возникло пару вопросов.1.  Как загрузить текст из директории программы в EditorGadget.2.  Как загрузить текст из любой папки на компе в EditorGadget.Накидал код и застопорился. Код прилагается.

Код:
;{- Enumerations / DataSections
;{ Windows
Enumeration
  #Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
  #Editor_1
  #Button_2
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 455, 62, 400, 400, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
   
      EditorGadget(#Editor_1, 20, 85, 345, 210)
      ButtonGadget(#Button_2, 35, 15, 75, 30, "Gadget_2")
   
  EndIf
EndProcedure

OpenWindow_Window_0()

;{- Event loop
Repeat
  Event = WaitWindowEvent()
  Select Event
    ; ///////////////////
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
      EventType = EventType()
      If EventGadget = #Editor_1
      ElseIf EventGadget = #Button_2
        File$ = OpenFileRequester("","C:/","Text (*.txt)|*.txt;*.bat|PureBasic (*.pb)|*.pb|All files (*.*)|*.*",0)
        If File$ 
          If ReadFile(0, File$) 
      Size = Lof(0) 
      *Text = AllocateMemory(Size) 
      If  *Text
        ReadData(0,  *Text, Size)  
        
      EndIf
      CloseFile(0)
      SetGadgetText(#Editor_1,PeekS(*Text))
    EndIf

      EndIf
      EndIf
    ; ////////////////////////
    Case #PB_Event_CloseWindow
      EventWindow = EventWindow()
      If EventWindow = #Window_0
        CloseWindow(#Window_0)
        Break
      EndIf
  EndSelect
ForEver
;
;}

Отредактировано Дмитрий (02.06.2011 18:46:21)

0

538

Спасибо!

0

539

Не совсем то, что нужно. Поэтому вопрос открыт.

0

540

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

Не совсем то, что нужно. Поэтому вопрос открыт.

что конкретно нужно!?

0


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