ListIconGadget with 2 windows and 5 StringGadgets

Just starting out? Need help? Post your questions and find answers here.
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

ListIconGadget with 2 windows and 5 StringGadgets

Post by Distorted Pixel »

Hi, I can't seem to get the program to put the entered text in each of the 5 StringGadgets when the "Ok" button is pressed on the second window to be put into the ListIconGadget next available "Item". Can't even get anything to show in debug either.

I have some InputRequesters Commented out that I originally had working perfectly. The entered information would be entered into the ListIcongadget perfectly, but I got the idea to create a second window and have the user be able to put all the information in on one window with stringGadgets, but I have failed so far. Below is the current code I have that shows I have tried a couple of things, but have failed with the second window idea so far

I would like the ability for the user to hit the "Return key" to advance to the next StringGadget also, currently only the "Tab key" works to advance it. I have a feeling that is default for the "Tab key" anyway.

Edit: (technically the program has 3 windows, but I'm not working with the help window yet more than what is already there)

You get the second window to pop up by clicking on the "Add Med" button

Code: Select all

; enumerated constants
Enumeration Window
  #Window
  #Window_1 = 1
  #Window_2 = 2
EndEnumeration

Enumeration File
  #File = 3
  #File_1 = 4
EndEnumeration

Enumeration gadget
  #gadget = 5
  #gadget_1 = 6
EndEnumeration

Enumeration Icongadget
  #Icongadget = 7
  #IconGadget_1 = 8
EndEnumeration

Enumeration ImageGadget
  #ImageGadget = 9
  #ImageGadget_1 = 10
EndEnumeration

Enumeration Button
  #Button = 11 ; Add Med button #Window
  #Button_1 = 12 ; Ok button #Window_1
EndEnumeration

Enumeration Toolbar
  #TOOLBAR = 13
EndEnumeration

Enumeration StatusBar
  #StatusBar = 14
EndEnumeration

Enumeration
  #StringGadget = 15
  #StringGadget_1 = 16
  #StringGadget_2 =17
  #StringGadget_3 = 18
  #StringGadget_4 = 19
  ;#StringGadget_5 = 20
EndEnumeration


#LVM_GETHEADER = #LVM_FIRST + 31 

; Globals 
Global oldListIconCallback, hHeader, redbrush, bluebrush 
redbrush=CreateSolidBrush_($9D9E9F)
bluebrush=CreateSolidBrush_($9D9E9F)


; Proc for subclassed ListIconGadget 
Procedure SubclassedListIcon(hwnd, msg, wparam, lparam) 
  Protected hdi.hd_item
  result = CallWindowProc_(oldListIconCallback, hwnd, msg, wparam, lparam) 
  Select msg 
    Case #WM_NOTIFY 
      *pnmh.NMHDR = lparam 
      ;--> Get handle to ListIcon header control 
      If *pnmh\code = #NM_CUSTOMDRAW
        *pnmcd.NMCUSTOMDRAW = lparam 
        ;--> Determine drawing stage 
        Select *pnmcd\dwDrawStage 
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
;Get header text.
            text$=Space(100)
            hdi\mask = #HDI_TEXT
            hdi\psztext = @text$
            hdi\cchtextmax = Len(text$)
            SendMessage_(hHeader, #HDM_GETITEM,*pnmcd\dwItemSpec,hdi)
;Check button state.
            If *pnmcd\uItemState & #CDIS_SELECTED
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
;Offset text because of the selected button.
              InflateRect_(*pnmcd\rc,-1,-1)
            Else
             DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH)
            EndIf
;Draw background.
;Here we alternate red text on blue background.
            InflateRect_(*pnmcd\rc,-1,-1)
            SetBkMode_(*pnmcd\hdc,#TRANSPARENT) 
            If *pnmcd\dwItemSpec&1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, redbrush)
              SetTextColor_(*pnmcd\hdc, $A0222222) 
            Else
              FillRect_(*pnmcd\hdc, *pnmcd\rc, bluebrush)
              SetTextColor_(*pnmcd\hdc, $A0222222) 
            EndIf
            DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_CENTER | #DT_VCENTER | #DT_END_ELLIPSIS)
            result = #CDRF_SKIPDEFAULT
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

; declare procedure to be able to place it at the bottom of program
Declare EnterInfo()
Declare MedsCompHelp()
Declare ButtonPressed()
; window constant settings
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget
; open a window to use for the program
If OpenWindow(#Window, 0, 0, 1024, 768, "Meds Companion", wFlags)
  Global Med.s, DoseStrength.s, NumDoses.s, IntendedUse.s, MedUses.s
  LoadFont(0, "Arial Black", 11, #PB_Font_Bold)
      
    ; toolbar menu
  If CreateMenu(0, WindowID(#Window))
    MenuTitle("Open")
    MenuItem(1, "New List")
    MenuItem(2, "Open List")
    OpenSubMenu("Recent Files")
    CloseSubMenu()
    MenuItem(3, "Save"   +Chr(9)+"Ctrl+S")
    MenuItem(4, "Save as"+Chr(9)+"Ctrl+A")
    MenuItem(5, "Close"  +Chr(9)+"Ctrl+C")
    MenuItem(6, "Quit")
    MenuTitle("Help")
    MenuItem(7, "Meds Companion help")
    MenuItem(8, "Online Medication lookup")
  EndIf
  ; create form to show and use information
  LFlags = #PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines | #PB_ListIcon_MultiSelect | #LVS_NOSORTHEADER
  
  ; create gadget for medication list
  ListIconGadget(#Icongadget, 1, 25, 1022, 700, "MEDICATION NAME", 150, LFlags)
  hHeader = SendMessage_(GadgetID(#Icongadget), #LVM_GETHEADER, 0, 0)
  ;Subclass ListIcon so we can customdraw the header text 
  oldListIconCallback = SetWindowLong_(GadgetID(#Icongadget), #GWL_WNDPROC, @SubclassedListIcon()) 
  ;set the gadget font, back color And line color
  SetGadgetFont(#Icongadget, FontID(0))
  SetGadgetColor(#Icongadget, #PB_Gadget_BackColor, $D0CDCECE)
  ;SetGadgetColor(#gadget, #PB_Gadget_LineColor, $D048494A)  
  ; add medication button
  ButtonGadget(#Button, 10, 0, 100, 25, "Add Med")
  
  ; add category columns
  AddGadgetColumn(#Icongadget, 1, "DOSAGE (mg)", 120)
  AddGadgetColumn(#Icongadget, 2, "DAILY DOSES", 110)
  AddGadgetColumn(#Icongadget, 3, "PRESCRIBED FOR", 240)
  AddGadgetColumn(#Icongadget, 4, "Medication Uses", 397)
  
  ; create statusbar at the bottom
  If CreateStatusBar(#StatusBar, WindowID(#Window))
    AddStatusBarField(155) ; total medications
    AddStatusBarField(83)  ; blank and borderless
    AddStatusBarField(90)  ; doses daily(Either total doses or total of the highlighted medication in the list
    AddStatusBarField(130) ; 
    AddStatusBarField(497)
  EndIf
  
  ; statusbar field text
  StatusBarText(#StatusBar, 0, "Total Medications", #PB_StatusBar_BorderLess)
  StatusBarText(#StatusBar, 1, "", #PB_StatusBar_Center | #PB_StatusBar_BorderLess)
  StatusBarText(#StatusBar, 2, "Total Daily Doses", #PB_StatusBar_Center | #PB_StatusBar_BorderLess) 
  FreeFont(0)
  
 ; main program loop  
Repeat
  Event = WaitWindowEvent()
  
  ; main menu detection
  Select Event
    Case #PB_Event_CloseWindow
      FreeGadget(#Icongadget)
      CloseWindow(#Window)
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case 1 ; start new medication list
          ClearGadgetItems(#Icongadget)
          
        Case 2 ; load saved medication list
          Input$ = InputRequester("Meds Companion", "Enter saved list name", "")
          If Input$ = ""
            MessageRequester("Meds Companion", Input$)
          Else
            a$ = "The requester was canceled or there was nothing entered."
            MessageRequester("Information", a$, 0)
          EndIf
        ; save current medication list
        Case 3
          Input$ = SaveFileRequester("Meds Companion","Untitled.txt", "Text (*.txt)|*.txt;*.bat|*.txt;*.dat|All files (*.*)|*.*", 0)
          
        ; quit program  
        Case 6
          ClearGadgetItems(#Icongadget)
          FreeGadget(#Icongadget)
          End
          MessageRequester("Information", a$, 0)
        Case 7
          MedsCompHelp()          
      EndSelect
  EndSelect
  ; enter new medication information
  ;If Event = #PB_Event_Gadget
    If EventGadget() = #Button
      EnterInfo()
    EndIf
  ;EndIf
    
Until Event = #PB_Event_CloseWindow
EndIf

; enter medication procedure
Procedure EnterInfo()
  InitSprite()
  InitKeyboard() 
  OpenWindow(#Window_1, 0, 0, 290, 280, "Meds Companion", #PB_Window_SystemMenu | #PB_Window_ScreenCentered, WindowID(#Window))
  
  LoadFont(0, "Arial", 10)
  CreateImage(0, 342, 300, 24, $D0D5D5D6)
  
  StartDrawing(ImageOutput(0))
  DrawingFont(FontID(0))
  DrawingMode(#PB_2DDrawing_Transparent)
  
  DrawText(5, 20, "Enter medication name", #Black, $D0A8A8A8)
  StringGadget(#StringGadget, 5, 37, 250, 20, Med)                              ;medication
  DrawText(5, 65, "Enter dosage strength", #Black, $D0A8A8A8)
  StringGadget(#StringGadget_1, 5, 83, 250, 20, DoseStrength$)                  ; dosage strength
  DrawText(5, 110, "Enter number of daily doses", #Black, $D0A8A8A8)
  StringGadget(#StringGadget_2, 5, 129, 250, 20, NumDoses$)                     ; number of daily doses
  DrawText(5, 152, "Enter what medication is proscribed for", #Black, $D0A8A8A8)
  StringGadget(#StringGadget_3, 5, 170, 250, 20, IntendedUse$)                  ; proscribed for
  DrawText(5, 195, " Enter medication uses", #Black, $D0A8A8A8)
  StringGadget(#StringGadget_4, 5, 214, 250, 20, MedUses$)                      ; uses for medication
  StopDrawing()
  SetActiveGadget(15);#StringGadget)
  
  ImageGadget(#ImageGadget, 0, 0, 342, 247, ImageID(0))
  ButtonGadget(#Button_1, 196, 245, 60, 25, "Ok")
  BindGadgetEvent(#Button_1, @ButtonPressed())
  ;Input_Med = StringGadget(#StringGadget,10, 130, 250, 20, "")
    
;   Med = InputRequester("Medication Companion", "Enter medication name", "")
;   DoseStrength = InputRequester("Medication Companion", "Enter dosage strength", "")
;   NumDoses     = InputRequester("Medication Companion", "Enter number of daily doses", "")
;   IntendedUse  = InputRequester("Medication Companion", "Enter what the medication is proscribed For", "")
;   MedUses      = InputRequester("Medication Companion", "Medication Uses", "")
  ;AddGadgetItem(#Icongadget, -1, Med$ + Chr(10) + DoseStrength$ + " mg" + Chr(10) + NumDoses$ + Chr(10) + IntendedUse$ + Chr(10) + MedUses$)
  SetGadgetItemColor(#Icongadget, -1, #PB_Gadget_FrontColor, $A0AA2222, #PB_All)
  
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_CloseWindow
        FreeGadget(12) ; button for window_1
        For a = 15 To 19
         FreeGadget(a)          
        Next a
        CloseWindow(#Window_1)
        Break
    EndSelect
    
    For i = 15 To 19
      If GetGadgetState(i)
        Debug i
        Break
      EndIf
    Next
    
  ForEver

EndProcedure

; help file procedure
Procedure MedsCompHelp()
; window constant settings
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget
OpenWindow(#Window_2, 0, 0, 950, 550, "Meds Companion help", wFlags, WindowID(#Window))

; open a window to use for the program
;OpenHelp("Help.chm", "Help\Help.html")

Repeat
  Event = WaitWindowEvent()
  
  If Event = #PB_Event_CloseWindow
    CloseWindow(3)
    Break
  EndIf
   
ForEver
EndProcedure

Procedure ButtonPressed()
  Protected i, Gadget = EventGadget()
  
  Debug Gadget
  For i = 15 To 19
    If i = Gadget
      Med = GetGadgetText(#StringGadget)
      DoseStrength = GetGadgetText(#StringGadget_1)
      NumDoses = GetGadgetText(#StringGadget_2)
      IntendedUse = GetGadgetText(#StringGadget_3)
      MedUses = GetGadgetText(#StringGadget_4)
      AddGadgetItem(#Icongadget, -1, Med + Chr(10) + DoseStrength + " mg" + Chr(10) + NumDoses + Chr(10) + IntendedUse + Chr(10) + MedUses)
    EndIf
  Next i
            
EndProcedure
Last edited by Distorted Pixel on Sat Mar 25, 2023 11:33 pm, edited 1 time in total.
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by infratec »

One eventloop per programm.
No more no less.

Then use EventWindow()
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by Distorted Pixel »

infratec wrote: Sat Mar 25, 2023 11:31 pm One eventloop per programm.
No more no less.

Then use EventWindow()
I happened to see something in the forum that someone was telling someone else about "one eventloop per program and saw their example, but I hadn't really tried it, but I guess I will dive right in and attempt to create "one eventloop". It will take awhile, but I'm up for the challenge

Thank you infratec
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by infratec »

A first working version:

Code: Select all

EnableExplicit

; enumerated constants
Enumeration Window
  #Window_Main
  #Window_EnterInfo
  #Window_Help
EndEnumeration

Enumeration File
  #File
  #File_1
EndEnumeration

Enumeration gadget
  #gadget
  #gadget_1
  #Icongadget
  #IconGadget_1
  #ImageGadgetEnterInfo
  #ImageGadget_1
  #ButtonAddMed ; Add Med button #Window
  #ButtonOkEnterInfo ; Ok button #Window_1
  #StringGadget_MedName
  #StringGadget_DoseStrength
  #StringGadget_NumDoses
  #StringGadget_IntendedUse
  #StringGadget_MedUse
  ;#StringGadget_5
EndEnumeration

Enumeration Toolbar
  #TOOLBAR
EndEnumeration

Enumeration StatusBar
  #StatusBar
EndEnumeration



#LVM_GETHEADER = #LVM_FIRST + 31 

Structure EnterInfo_Structure
  Med$
  DoseStrength$
  NumDoses$
  IntendedUse$
  MedUses$
EndStructure


; Globals 
Global oldListIconCallback, hHeader, redbrush, bluebrush 
redbrush=CreateSolidBrush_($9D9E9F)
bluebrush=CreateSolidBrush_($9D9E9F)


; Proc for subclassed ListIconGadget 
Procedure SubclassedListIcon(hwnd, msg, wparam, lparam) 
  
  Protected hdi.hd_item, result.i, *pnmh.NMHDR, *pnmcd.NMCUSTOMDRAW, text$
  
  
  result = CallWindowProc_(oldListIconCallback, hwnd, msg, wparam, lparam) 
  Select msg 
    Case #WM_NOTIFY 
      *pnmh = lparam
      ;--> Get handle to ListIcon header control 
      If *pnmh\code = #NM_CUSTOMDRAW
        *pnmcd = lparam 
        ;--> Determine drawing stage 
        Select *pnmcd\dwDrawStage 
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
            ;Get header text.
            text$=Space(100)
            hdi\mask = #HDI_TEXT
            hdi\psztext = @text$
            hdi\cchtextmax = Len(text$)
            SendMessage_(hHeader, #HDM_GETITEM,*pnmcd\dwItemSpec,hdi)
            ;Check button state.
            If *pnmcd\uItemState & #CDIS_SELECTED
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
              ;Offset text because of the selected button.
              InflateRect_(*pnmcd\rc,-1,-1)
            Else
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH)
            EndIf
            ;Draw background.
            ;Here we alternate red text on blue background.
            InflateRect_(*pnmcd\rc,-1,-1)
            SetBkMode_(*pnmcd\hdc,#TRANSPARENT) 
            If *pnmcd\dwItemSpec&1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, redbrush)
              SetTextColor_(*pnmcd\hdc, $A0222222) 
            Else
              FillRect_(*pnmcd\hdc, *pnmcd\rc, bluebrush)
              SetTextColor_(*pnmcd\hdc, $A0222222) 
            EndIf
            DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_CENTER | #DT_VCENTER | #DT_END_ELLIPSIS)
            result = #CDRF_SKIPDEFAULT
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 




; enter medication procedure
Procedure OpenEnterInfo(*Info.EnterInfo_Structure)
  
  Protected Tmp.i
  
  OpenWindow(#Window_EnterInfo, 0, 0, 290, 280, "Meds Companion", #PB_Window_SystemMenu | #PB_Window_WindowCentered, WindowID(#Window_Main))
  SetWindowColor(#Window_EnterInfo, $D5D5D5)
  
  LoadFont(0, "Arial", 10)
  SetGadgetFont(#PB_Default, FontID(0))
  
  Tmp = TextGadget(#PB_Any, 5, 20, 200, 20, "Enter medication name")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_MedName, 5, 37, 250, 20, *Info\Med$)
  
  Tmp = TextGadget(#PB_Any, 5, 65, 200, 20,  "Enter dosage strength")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_DoseStrength, 5, 83, 250, 20, *Info\DoseStrength$)
  
  Tmp = TextGadget(#PB_Any, 5, 110, 200, 20,  "Enter number of daily doses")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_NumDoses, 5, 129, 250, 20, *Info\NumDoses$)
  
  Tmp = TextGadget(#PB_Any, 5, 152, 200, 20,  "Enter what medication is proscribed for")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_IntendedUse, 5, 170, 250, 20, *Info\IntendedUse$)
  
  Tmp = TextGadget(#PB_Any, 5, 195, 200, 20,  " Enter medication uses")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_MedUse, 5, 214, 250, 20, *Info\MedUses$)
  
  SetActiveGadget(#StringGadget_MedName)
  
  ButtonGadget(#ButtonOkEnterInfo, 196, 245, 60, 25, "Ok")
  
  SetGadgetItemColor(#Icongadget, -1, #PB_Gadget_FrontColor, $A0AA2222, #PB_All)
  
  SetGadgetFont(#PB_Default, #PB_Default)
  
EndProcedure

; help file procedure
Procedure MedsCompHelp()
  
  Protected wFlags.i
  
  ; window constant settings
  wFlags = #PB_Window_SystemMenu | #PB_Window_WindowCentered |#PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget
  OpenWindow(#Window_Help, 0, 0, 950, 550, "Meds Companion help", wFlags, WindowID(#Window_Main))
  
  ; open a window to use for the program
  ;OpenHelp("Help.chm", "Help\Help.html")
  
EndProcedure



;-Main

Define.i wFlags, LFlags, Event, Exit
Define Input$, a$
Define EnterInfo.EnterInfo_Structure

; window constant settings
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget
; open a window to use for the program
If OpenWindow(#Window_Main, 0, 0, 1024, 768, "Meds Companion", wFlags)
  
  LoadFont(0, "Arial Black", 11, #PB_Font_Bold)
  
  ; toolbar menu
  If CreateMenu(0, WindowID(#Window_Main))
    MenuTitle("Open")
    MenuItem(1, "New List")
    MenuItem(2, "Open List")
    OpenSubMenu("Recent Files")
    CloseSubMenu()
    MenuItem(3, "Save"   +Chr(9)+"Ctrl+S")
    MenuItem(4, "Save as"+Chr(9)+"Ctrl+A")
    MenuItem(5, "Close"  +Chr(9)+"Ctrl+C")
    MenuItem(6, "Quit")
    MenuTitle("Help")
    MenuItem(7, "Meds Companion help")
    MenuItem(8, "Online Medication lookup")
  EndIf
  ; create form to show and use information
  LFlags = #PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines | #PB_ListIcon_MultiSelect | #LVS_NOSORTHEADER
  
  ; create gadget for medication list
  ListIconGadget(#Icongadget, 1, 25, 1022, 700, "MEDICATION NAME", 150, LFlags)
  hHeader = SendMessage_(GadgetID(#Icongadget), #LVM_GETHEADER, 0, 0)
  ;Subclass ListIcon so we can customdraw the header text 
  oldListIconCallback = SetWindowLong_(GadgetID(#Icongadget), #GWL_WNDPROC, @SubclassedListIcon()) 
  ;set the gadget font, back color And line color
  SetGadgetFont(#Icongadget, FontID(0))
  SetGadgetColor(#Icongadget, #PB_Gadget_BackColor, $D0CDCECE)
  ;SetGadgetColor(#gadget, #PB_Gadget_LineColor, $D048494A)  
  ; add medication button
  ButtonGadget(#ButtonAddMed, 10, 0, 100, 25, "Add Med")
  
  ; add category columns
  AddGadgetColumn(#Icongadget, 1, "DOSAGE (mg)", 120)
  AddGadgetColumn(#Icongadget, 2, "DAILY DOSES", 110)
  AddGadgetColumn(#Icongadget, 3, "PRESCRIBED FOR", 240)
  AddGadgetColumn(#Icongadget, 4, "Medication Uses", 397)
  
  ; create statusbar at the bottom
  If CreateStatusBar(#StatusBar, WindowID(#Window_Main))
    AddStatusBarField(155) ; total medications
    AddStatusBarField(83)  ; blank and borderless
    AddStatusBarField(90)  ; doses daily(Either total doses or total of the highlighted medication in the list
    AddStatusBarField(130) ; 
    AddStatusBarField(497)
  EndIf
  
  ; statusbar field text
  StatusBarText(#StatusBar, 0, "Total Medications", #PB_StatusBar_BorderLess)
  StatusBarText(#StatusBar, 1, "", #PB_StatusBar_Center | #PB_StatusBar_BorderLess)
  StatusBarText(#StatusBar, 2, "Total Daily Doses", #PB_StatusBar_Center | #PB_StatusBar_BorderLess) 
  FreeFont(0)
  
  ;- main program loop  
  Repeat
    Event = WaitWindowEvent()
    
    Select EventWindow()
      Case #Window_Main
        Select Event
          Case #PB_Event_CloseWindow
            CloseWindow(#Window_Main)
            Exit = #True
            
          Case #PB_Event_Menu
            Select EventMenu()
              Case 1 ; start new medication list
                ClearGadgetItems(#Icongadget)
                
              Case 2 ; load saved medication list
                Input$ = InputRequester("Meds Companion", "Enter saved list name", "")
                If Input$ = ""
                  MessageRequester("Meds Companion", Input$)
                Else
                  a$ = "The requester was canceled or there was nothing entered."
                  MessageRequester("Information", a$, 0)
                EndIf
                ; save current medication list
                
              Case 3
                Input$ = SaveFileRequester("Meds Companion","Untitled.txt", "Text (*.txt)|*.txt;*.bat|*.txt;*.dat|All files (*.*)|*.*", 0)
                
                ; quit program  
              Case 6
                Exit = #True
                
              Case 7
                MedsCompHelp()          
                
            EndSelect
            
          Case #PB_Event_Gadget
            Select EventGadget()
              Case #ButtonAddMed
                OpenEnterInfo(@EnterInfo)
            EndSelect
        EndSelect
        
      Case #Window_EnterInfo
        Select Event
          Case #PB_Event_CloseWindow
            CloseWindow(#Window_EnterInfo)
            SetActiveWindow(#Window_Main)
            
          Case #PB_Event_Gadget
            Select EventGadget()
              Case #ButtonOkEnterInfo
                EnterInfo\Med$ = GetGadgetText(#StringGadget_MedName)
                EnterInfo\DoseStrength$ = GetGadgetText(#StringGadget_DoseStrength)
                EnterInfo\NumDoses$ = GetGadgetText(#StringGadget_NumDoses)
                EnterInfo\IntendedUse$ = GetGadgetText(#StringGadget_IntendedUse)
                EnterInfo\MedUses$ = GetGadgetText(#StringGadget_MedUse)
                AddGadgetItem(#Icongadget, -1, EnterInfo\Med$ + #LF$ + EnterInfo\DoseStrength$ + " mg" + #LF$ + EnterInfo\NumDoses$ + #LF$ + EnterInfo\IntendedUse$ + #LF$ + EnterInfo\MedUses$)
                
                PostEvent(#PB_Event_CloseWindow, #Window_EnterInfo, 0)
            EndSelect
        EndSelect
        
      Case #Window_Help
        Select Event
          Case #PB_Event_CloseWindow
            CloseWindow(#Window_Help)
            SetActiveWindow(#Window_Main)
        EndSelect
        
    EndSelect
    
  Until Exit
EndIf
You should use better names.
Why InitSprite() and InitKeyboard() :?: :?: :?:
Why BindEvent for a button?
Why the For loops for the Gadgets()?

Enumerations are for automatic generation of the numbers. why you set them by 'hand'?

Use always EnableExplicit as first command.
Else you run into trouble with larger codes.

Avoid Globals where you can.
Use a structure and use a *pointer to it as procedure parameter
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by infratec »

Now I'm finished with changes, because I go to sleep.
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by Distorted Pixel »

infratec wrote: Sun Mar 26, 2023 12:02 am A first working version:
Wow, thank you infratec for your effort on this. That was really fast. I was looking forward to the challenge of creating my first muli-window application and have worked on this after work every day for about 2 weeks. I was also looking forward to the challenge of the "one eventloop" work. I guarantee I will spend a lot of time learning from this. I will save my code and see if I can write my own "one eventloop" and see if it is as good as yours.



Thank you again infratec


You should use better names.
Why InitSprite() and InitKeyboard() :?: :?: :?:
Why BindEvent for a button?
Why the For loops for the Gadgets()?
It was what was left of me trying to use OpenScreen to use the KeyboardShortcuts in trying to get the StringGadgets and the button to work. I forgot to delete it.

BindEvent I thought is what we had to use to tie code to the buttons to get them to work

Loops for gadgets? Not exactly sure what loops your talking about
Enumerations are for automatic generation of the numbers. why you set them by 'hand'?
I was confused about Enumerations for awhile. I had trouble figuring them out so after I researched and learned I was trying to count them. Seeing a number there helps me remember what they are.
Use always EnableExplicit as first command.
Else you run into trouble with larger codes.

Avoid Globals where you can.
Use a structure and use a *pointer to it as procedure parameter
Thank you very much, I will try to remember this.

I have a lot to learn still is why all the crappy code. I consider myself a little better than a beginner, but not a intermediate coder yet by far. I still have a long way to go in learning.
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by infratec »

Gadget loop in your original code:

Code: Select all

Procedure ButtonPressed()
  Protected i, Gadget = EventGadget()
  
  Debug Gadget
  For i = 15 To 19
    If i = Gadget
      Med = GetGadgetText(#StringGadget)
      DoseStrength = GetGadgetText(#StringGadget_1)
      NumDoses = GetGadgetText(#StringGadget_2)
      IntendedUse = GetGadgetText(#StringGadget_3)
      MedUses = GetGadgetText(#StringGadget_4)
      AddGadgetItem(#Icongadget, -1, Med + Chr(10) + DoseStrength + " mg" + Chr(10) + NumDoses + Chr(10) + IntendedUse + Chr(10) + MedUses)
    EndIf
  Next i
            
EndProcedure
Also if you close a window the complete content is freed automatically.
You don't need to free all gadgets by self.
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by Distorted Pixel »

infratec wrote: Sun Mar 26, 2023 9:48 am Gadget loop in your original code:

Code: Select all

Procedure ButtonPressed()
  Protected i, Gadget = EventGadget()
  
  Debug Gadget
  For i = 15 To 19
    If i = Gadget
      Med = GetGadgetText(#StringGadget)
      DoseStrength = GetGadgetText(#StringGadget_1)
      NumDoses = GetGadgetText(#StringGadget_2)
      IntendedUse = GetGadgetText(#StringGadget_3)
      MedUses = GetGadgetText(#StringGadget_4)
      AddGadgetItem(#Icongadget, -1, Med + Chr(10) + DoseStrength + " mg" + Chr(10) + NumDoses + Chr(10) + IntendedUse + Chr(10) + MedUses)
    EndIf
  Next i
            
EndProcedure
Also if you close a window the complete content is freed automatically.
You don't need to free all gadgets by self.
Oh yea, I was trying anything I could come up with to get the "Ok" button to work and the information show up in the listicon.
For the life of me I could not get the "Ok" button to work. I tried For/Next loops and binding, Select/EndSelect and I've even tried an If/Endif thing in the Repeat/Until or ForEver loop
Everything failed lol

I'm learning to program with PB more and more. I have finally started to use more enumerated constants now, I have always been afraid or confused of things like enumerated constants and even more afraid or confused of arrays.

I can do arrays if they are basic, but if they are structured arrays or complex-structured they confuse me. It takes me a couple of hours to a couple of days to slowly figure out what things are and what it is doing.

The (.) between two words really confuses me because I can't remember each word is indicating. I think one is the array name and the other a variable in the structure or something. Ugh lol

Pointers is yet another thing I have not tried to use yet.
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by mk-soft »

Please have a look at this one before working with BindGadgetEvent.

- First of all, you need to have a clean event loop management running and only once.
- With enumeration you should not assign values (only in special cases). Enumeration automatically increments the value.
- For each object type windows, menus, gadgets there should always be only one enumeration to avoid double assignment.

Update

Code: Select all

;-TOP

#ProgramTitle = "Main Window"
#ProgramVersion = "v1.01.2"

Enumeration Windows
  #MainWindow
  #DialogWindow
EndEnumeration

Enumeration MenuBar
  #MainWindowMenu
EndEnumeration

Enumeration MenuItems
  #MainWindowMenuAbout
  #MainWindowMenuExit
  #MainWindowMenuOpenDialog
EndEnumeration

Enumeration Gadgets
  ; Main gadgets
  #MainWindowEdit
  #MainWindowButtonOk
  #MainWindowButtonCancel
  ; Diaglog gadgets
  #DialogWindowList
  #DialogWindowButtonOk
  #DialogWindowButtonCancel
EndEnumeration

Enumeration StatusBar
  #MainWindowStatusBar
EndEnumeration

; ----

Procedure UpdateMainWindow()
  Protected dx, dy
  dx = WindowWidth(#MainWindow)
  dy = WindowHeight(#MainWindow) - StatusBarHeight(#MainWindowStatusBar) - MenuHeight()
  ; Resize gadgets
  ResizeGadget(#MainWindowEdit, 5, 5, dx - 10, dy - 45)
  ResizeGadget(#MainWindowButtonok, 10, dy - 35, 120, 30)
  ResizeGadget(#MainWindowButtonCancel, dx - 130, dy - 35, 120, 30)
EndProcedure

Procedure UpdateDialogWindow()
  Protected dx, dy
  dx = WindowWidth(#DialogWindow)
  dy = WindowHeight(#DialogWindow)
  ; Resize gadgets
  ResizeGadget(#DialogWindowList, 5, 5, dx - 10, dy - 45)
  ResizeGadget(#DialogWindowButtonOk, 10, dy - 35, 120, 30)
  ResizeGadget(#DialogWindowButtonCancel, dx - 130, dy - 35, 120, 30)
EndProcedure

; ----

Procedure ShowDialogWindow()
  Protected dx, dy
  
  #DialogWindowStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#DialogWindow, #PB_Ignore, #PB_Ignore, 600, 400, "Dialog" , #DialogWindowStyle, WindowID(#MainWindow))
    ; Gadgets
    dx = WindowWidth(#DialogWindow)
    dy = WindowHeight(#DialogWindow)
    ListViewGadget(#DialogWindowList, 5, 5, dx -10, dy - 45)
    ButtonGadget(#DialogWindowButtonok, 10, dy - 35, 120, 30, "Ok")
    ButtonGadget(#DialogWindowButtonCancel, dx - 130, dy - 35, 120, 30, "Cancel")
    
    BindEvent(#PB_Event_SizeWindow, @UpdateDialogWindow(), #DialogWindow)
  EndIf
EndProcedure

Procedure Main()
  Protected dx, dy
  
  #MainWindowStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#MainWindow, #PB_Ignore, #PB_Ignore, 800, 600, #ProgramTitle , #MainWindowStyle)
    ; Menu
    CreateMenu(#MainWindowMenu, WindowID(#MainWindow))
    MenuTitle("&File")
    MenuItem(#MainWindowMenuAbout, "About")
    MenuBar()
    MenuItem(#MainWindowMenuExit, "E&xit")
    MenuTitle("&Dialog")
    MenuItem(#MainWindowMenuOpenDialog, "&Open")
    
    ; StatusBar
    CreateStatusBar(#MainWindowStatusBar, WindowID(#MainWindow))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(#MainWindow)
    dy = WindowHeight(#MainWindow) - StatusBarHeight(#MainWindowStatusBar) - MenuHeight()
    EditorGadget(#MainWindowEdit, 5, 5, dx -10, dy - 45)
    ButtonGadget(#MainWindowButtonok, 10, dy - 35, 120, 30, "Ok")
    ButtonGadget(#MainWindowButtonCancel, dx - 130, dy - 35, 120, 30, "Cancel")
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateMainWindow(), #MainWindow)
    
    ; Event Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case #MainWindow
              Break
              
            Case #DialogWindow
              Debug "Close DialogWindow"
              ;TODO befor close dialog window 
              CloseWindow(#DialogWindow)
              
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            
            Case #MainWindowMenuAbout
              MessageRequester("About", #ProgramTitle + #LF$ + #ProgramVersion, #PB_MessageRequester_Info)
                
            Case #MainWindowMenuExit
              PostEvent(#PB_Event_CloseWindow, #MainWindow, #Null)
              
            Case #MainWindowMenuOpenDialog
              If Not IsWindow(#DialogWindow)
                ShowDialogWindow()
              EndIf
              
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #MainWindowEdit
              Select EventType()
                Case #PB_EventType_Change
                  ;
                  
              EndSelect
              
            Case #MainWindowButtonOk
              Debug "#MainWindowButtonOk"
              
            Case #MainWindowButtonCancel
              Debug "#MainWindowButtonCancel"
              
            Case #DialogWindowButtonOk
              Debug "#DialogWindowButtonOk"
              
            Case #DialogWindowButtonCancel
              Debug "#DialogWindowButtonCancel"
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by Distorted Pixel »

- With enumeration you should not assign values (only in special cases). Enumeration automatically increments the value.
- For each object type windows, menus, gadgets there should always be only one enumeration to avoid double assignment.
When I first started using Enumerations for this program, I put all the constants in one Enumeration/EndEnumeration block. I knew they were suppose to automatically increment the values so I thought at that time they would work because they should increment, but it failed. Why I couldn't tell you, but it did.

So I decided to put each type of constant in it's own block, but still failed. I had to count from top to bottom to figure out what value was being assigned to the ButtonGadgets and StringGadgets to get it to work. I even put the constant name where the #Gadget number was suppose to go and it failed. Hmm. I must have had the wrong constant somewhere eventhough one was the right one, somewhere one was probably wrong for it to fail.

I will look at your latest code posted, I tried it alread and some of the options work. I realize to make a point you only had certain ones set up completely. Anyway I will look at the code and figure out what is going on and learn from it

Edit: what is #LF$? I have not seen it before. Is it simular or the same as "Break"?

Also could you explain the following Define? Periods between words confuses me as I explained arrays in earlier post
This define is from the first code you posted

Define EnterInfo.EnterInfo_Structure
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by Distorted Pixel »

Ok, I have added a save routine which works, but if you try to open the .txt or .dat file with Note Pad or NotePad++ I get "error 6". I have to open it up with Word Pad for it to open successfully. Is that a problem? I know the save routine needs to be under the "Save As" option, I'll change it tomorrow.

https://mega.nz/file/4wsAzJ7I#lCZWMxkLi ... UPY2w2YVHw

I also set the StringGadgets to be empty each time you click the "Add Med" button

Code: Select all

EnableExplicit

; enumerated constants
Enumeration Window
  #Window_Main
  #Window_EnterInfo
  #Window_Help
EndEnumeration

Enumeration File
  #File
  #File_1
EndEnumeration

Enumeration gadget
  #gadget
  #gadget_1
  #Icongadget
  #IconGadget_1
  #ImageGadgetEnterInfo
  #ImageGadget_1
  #ButtonAddMed ; Add Med button #Window
  #ButtonOkEnterInfo ; Ok button #Window_1
  #StringGadget_MedName
  #StringGadget_DoseStrength
  #StringGadget_NumDoses
  #StringGadget_IntendedUse
  #StringGadget_MedUse
  ;#StringGadget_5
EndEnumeration

Enumeration Toolbar
  #TOOLBAR
EndEnumeration

Enumeration StatusBar
  #StatusBar
EndEnumeration



#LVM_GETHEADER = #LVM_FIRST + 31 

Structure EnterInfo_Structure
  Med$
  DoseStrength$
  NumDoses$
  IntendedUse$
  MedUses$
  Med.i
  DoseStrength.i
  NumDoses.i
  IntendedUse.i
  MedUses.i
EndStructure

; Globals 
Global oldListIconCallback, hHeader, redbrush, bluebrush 
redbrush=CreateSolidBrush_($9D9E9F)
bluebrush=CreateSolidBrush_($9D9E9F)


; Proc for subclassed ListIconGadget 
Procedure SubclassedListIcon(hwnd, msg, wparam, lparam) 
  
  Protected hdi.hd_item, result.i, *pnmh.NMHDR, *pnmcd.NMCUSTOMDRAW, text$
  
  
  result = CallWindowProc_(oldListIconCallback, hwnd, msg, wparam, lparam) 
  Select msg 
    Case #WM_NOTIFY 
      *pnmh = lparam
      ;--> Get handle to ListIcon header control 
      If *pnmh\code = #NM_CUSTOMDRAW
        *pnmcd = lparam 
        ;--> Determine drawing stage 
        Select *pnmcd\dwDrawStage 
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
            ;Get header text.
            text$=Space(100)
            hdi\mask = #HDI_TEXT
            hdi\psztext = @text$
            hdi\cchtextmax = Len(text$)
            SendMessage_(hHeader, #HDM_GETITEM,*pnmcd\dwItemSpec,hdi)
            ;Check button state.
            If *pnmcd\uItemState & #CDIS_SELECTED
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
              ;Offset text because of the selected button.
              InflateRect_(*pnmcd\rc,-1,-1)
            Else
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH)
            EndIf
            ;Draw background.
            ;Here we alternate red text on blue background.
            InflateRect_(*pnmcd\rc,-1,-1)
            SetBkMode_(*pnmcd\hdc,#TRANSPARENT) 
            If *pnmcd\dwItemSpec&1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, redbrush)
              SetTextColor_(*pnmcd\hdc, $A0222222) 
            Else
              FillRect_(*pnmcd\hdc, *pnmcd\rc, bluebrush)
              SetTextColor_(*pnmcd\hdc, $A0222222) 
            EndIf
            DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_CENTER | #DT_VCENTER | #DT_END_ELLIPSIS)
            result = #CDRF_SKIPDEFAULT
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure


Procedure SaveMedList()
  Define Input$, text$
  Define.i lastItem, item, column
  Input$ = SaveFileRequester("Meds Companion","Untitled.txt", "Text (*.txt)|*.txt;*.bat|*.txt;*.dat|All files (*.*)|*.*", 0)
  lastItem = CountGadgetItems(#Icongadget)
  CreateFile(0, Input$)
  For item = 0 To lastItem
    text$ = GetGadgetItemText(#Icongadget, item, 0)
    For column = 1 To 6
      text$ + " " + GetGadgetItemText(#Icongadget, item, column)
    Next column
    WriteStringN(0, text$, #PB_Ascii)
  Next item
  CloseFile(0)
EndProcedure

;---------------------------------------------------------------------
; enter medication procedure
Procedure OpenEnterInfo(*Info.EnterInfo_Structure)
  
  Protected Tmp.i
  
  OpenWindow(#Window_EnterInfo, 0, 0, 290, 280, "Meds Companion", #PB_Window_SystemMenu | #PB_Window_WindowCentered, WindowID(#Window_Main))
  SetWindowColor(#Window_EnterInfo, $D5D5D5)
  
  LoadFont(0, "Arial", 10)
  SetGadgetFont(#PB_Default, FontID(0))
  
  Tmp = TextGadget(#PB_Any, 5, 20, 250, 20, "Enter medication name")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_MedName, 5, 37, 250, 20, *Info\Med$)
  SetGadgetText(#StringGadget_MedName, "")
  
  Tmp = TextGadget(#PB_Any, 5, 65, 250, 20,  "Enter dosage strength")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_DoseStrength, 5, 83, 250, 20, *Info\DoseStrength$)
  SetGadgetText(#StringGadget_DoseStrength, "")
  
  Tmp = TextGadget(#PB_Any, 5, 110, 250, 20,  "Enter number of daily doses")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_NumDoses, 5, 129, 250, 20, *Info\NumDoses$)
  SetGadgetText(#StringGadget_NumDoses, "")
  
  Tmp = TextGadget(#PB_Any, 5, 152, 250, 20,  "Enter what medication is proscribed for")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_IntendedUse, 5, 170, 250, 20, *Info\IntendedUse$)
  SetGadgetText(#StringGadget_IntendedUse, "")
  
  Tmp = TextGadget(#PB_Any, 5, 195, 250, 20,  " Enter medication uses")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_MedUse, 5, 214, 250, 20, *Info\MedUses$)
  SetActiveGadget(#StringGadget_MedName)
  SetGadgetText(#StringGadget_MedUse, "")
  
  ButtonGadget(#ButtonOkEnterInfo, 196, 245, 60, 25, "Ok")
  
  ;SetGadgetItemColor(#Icongadget, -1, #PB_Gadget_FrontColor, $A0AA2222, #PB_All)
  
  SetGadgetFont(#PB_Default, #PB_Default)
  
EndProcedure
;--------------------------------------------------------------------------------
; help file procedure
Procedure MedsCompHelp()
  
  Protected wFlags.i
  
  ; window constant settings
  wFlags = #PB_Window_SystemMenu | #PB_Window_WindowCentered |#PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget
  OpenWindow(#Window_Help, 0, 0, 950, 550, "Meds Companion help", wFlags, WindowID(#Window_Main))
  
  ; open a window to use for the program
  ;OpenHelp("Help.chm", "Help\Help.html")
  
EndProcedure
;------------------------------------------------------------------------------------
;-Main

Define.i wFlags, LFlags, Event, Exit, lastItem, item, column
Define Input$, a$, text$
Define EnterInfo.EnterInfo_Structure

; window constant settings
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget
; open a window to use for the program
If OpenWindow(#Window_Main, 0, 0, 1024, 768, "Meds Companion", wFlags)
  
  LoadFont(0, "Arial", 11, #PB_Font_Bold)
  
  ; toolbar menu
  If CreateMenu(0, WindowID(#Window_Main))
    MenuTitle("Open")
    MenuItem(1, "New List")
    MenuItem(2, "Open List")
    OpenSubMenu("Recent Files")
    CloseSubMenu()
    MenuItem(3, "Save"   +Chr(9)+"Ctrl+S")
    MenuItem(4, "Save as"+Chr(9)+"Ctrl+A")
    MenuItem(5, "Close"  +Chr(9)+"Ctrl+C")
    MenuItem(6, "Quit")
    MenuTitle("Help")
    MenuItem(7, "Meds Companion help")
    MenuItem(8, "Online Medication lookup")
  EndIf
  ; create form to show and use information
  LFlags = #PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines | #PB_ListIcon_MultiSelect | #LVS_NOSORTHEADER
  
  ; create gadget for medication list
  ListIconGadget(#Icongadget, 1, 25, 1022, 700, "MEDICATION NAME", 150, LFlags)
  hHeader = SendMessage_(GadgetID(#Icongadget), #LVM_GETHEADER, 0, 0)
  ;Subclass ListIcon so we can customdraw the header text 
  oldListIconCallback = SetWindowLong_(GadgetID(#Icongadget), #GWL_WNDPROC, @SubclassedListIcon()) 
  ;set the gadget font, back color And line color
  SetGadgetFont(#Icongadget, FontID(0))
  SetGadgetColor(#Icongadget, #PB_Gadget_BackColor, $D0CDCECE)
  ;SetGadgetColor(#gadget, #PB_Gadget_LineColor, $D048494A)  
  ; add medication button
  ButtonGadget(#ButtonAddMed, 10, 0, 100, 25, "Add Med")
  
  ; add category columns
  AddGadgetColumn(#Icongadget, 1, "DOSAGE (mg)", 120)
  AddGadgetColumn(#Icongadget, 2, "DAILY DOSES", 110)
  AddGadgetColumn(#Icongadget, 3, "PRESCRIBED FOR", 240)
  AddGadgetColumn(#Icongadget, 4, "Medication Uses", 397)
  
  ; create statusbar at the bottom
  If CreateStatusBar(#StatusBar, WindowID(#Window_Main))
    AddStatusBarField(155) ; total medications
    AddStatusBarField(83)  ; blank and borderless
    AddStatusBarField(90)  ; doses daily(Either total doses or total of the highlighted medication in the list)
    AddStatusBarField(130) ; 
    AddStatusBarField(497)
  EndIf
  
  ; statusbar field text
  StatusBarText(#StatusBar, 0, "Total Medications", #PB_StatusBar_BorderLess)
  StatusBarText(#StatusBar, 1, "", #PB_StatusBar_Center | #PB_StatusBar_BorderLess)
  StatusBarText(#StatusBar, 2, "Total Daily Doses", #PB_StatusBar_Center | #PB_StatusBar_BorderLess) 
  FreeFont(0)
  
  ;- main program loop  
  Repeat
    Event = WaitWindowEvent()
    
    Select EventWindow()
      Case #Window_Main
        Select Event
          Case #PB_Event_CloseWindow
            CloseWindow(#Window_Main)
            Exit = #True
            
          Case #PB_Event_Menu
            Select EventMenu()
              Case 1 ; start new medication list
                ClearGadgetItems(#Icongadget)
                
              Case 2 ; load saved medication list
                Input$ = InputRequester("Meds Companion", "Enter saved list name", "")
                If Input$ = ""
                  MessageRequester("Meds Companion", Input$)
                Else
                  a$ = "The requester was canceled or there was nothing entered."
                  MessageRequester("Information", a$, 0)
                EndIf
                ; save current medication list
                
              Case 3
                SaveMedList()
                
                ; quit program  
              Case 6
                Exit = #True
                
              Case 7
                MedsCompHelp()          
                
            EndSelect
            
          Case #PB_Event_Gadget
            Select EventGadget()
              Case #ButtonAddMed
                OpenEnterInfo(@EnterInfo)
            EndSelect
        EndSelect
        
      Case #Window_EnterInfo
        Select Event
          Case #PB_Event_CloseWindow
            CloseWindow(#Window_EnterInfo)
            SetActiveWindow(#Window_Main)
            
          Case #PB_Event_Gadget
            Select EventGadget()
              Case #ButtonOkEnterInfo
                EnterInfo\Med$ = GetGadgetText(#StringGadget_MedName)
                EnterInfo\DoseStrength$ = GetGadgetText(#StringGadget_DoseStrength)
                EnterInfo\NumDoses$ = GetGadgetText(#StringGadget_NumDoses)
                EnterInfo\IntendedUse$ = GetGadgetText(#StringGadget_IntendedUse)
                EnterInfo\MedUses$ = GetGadgetText(#StringGadget_MedUse)
                AddGadgetItem(#Icongadget, -1, EnterInfo\Med$ + #LF$ + EnterInfo\DoseStrength$ + " mg" + #LF$ + EnterInfo\NumDoses$ + #LF$ + EnterInfo\IntendedUse$ + #LF$ + EnterInfo\MedUses$)
                PostEvent(#PB_Event_CloseWindow, #Window_EnterInfo, 0)
                
            EndSelect
        EndSelect
        
      Case #Window_Help
        Select Event
          Case #PB_Event_CloseWindow
            CloseWindow(#Window_Help)
            SetActiveWindow(#Window_Main)
        EndSelect
        
    EndSelect
    
  Until Exit
EndIf
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by infratec »

I c an open the file without problems.
But still your procedure is wrong and unsafe.

A better version:

Code: Select all

Procedure SaveMedList()
  Protected Input$, text$
  Protected.i lastItem, item, column
  Input$ = SaveFileRequester("Meds Companion","Untitled.txt", "Text (*.txt)|*.txt;*.bat|*.txt;*.dat|All files (*.*)|*.*", 0)
  If Input$
    lastItem = CountGadgetItems(#Icongadget)
    If CreateFile(0, Input$)
      For item = 0 To lastItem - 1
        text$ = GetGadgetItemText(#Icongadget, item, 0)
        For column = 0 To 5
          text$ + " " + GetGadgetItemText(#Icongadget, item, column)
        Next column
        WriteStringN(0, text$, #PB_Ascii)
      Next item
      CloseFile(0)
    EndIf
  EndIf
EndProcedure
#LF$ means Chr($0A)
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

Re: ListIconGadget with 2 windows and 5 StringGadgets

Post by Distorted Pixel »

infratec wrote: Mon Mar 27, 2023 8:03 am I c an open the file without problems.
But still your procedure is wrong and unsafe.

A better version:

Code: Select all

Procedure SaveMedList()
  Protected Input$, text$
  Protected.i lastItem, item, column
  Input$ = SaveFileRequester("Meds Companion","Untitled.txt", "Text (*.txt)|*.txt;*.bat|*.txt;*.dat|All files (*.*)|*.*", 0)
  If Input$
    lastItem = CountGadgetItems(#Icongadget)
    If CreateFile(0, Input$)
      For item = 0 To lastItem - 1
        text$ = GetGadgetItemText(#Icongadget, item, 0)
        For column = 0 To 5
          text$ + " " + GetGadgetItemText(#Icongadget, item, column)
        Next column
        WriteStringN(0, text$, #PB_Ascii)
      Next item
      CloseFile(0)
    EndIf
  EndIf
EndProcedure
#LF$ means Chr($0A)
Thank you, I do like your version better. Although I did figure out why I couldn't open any .txt or .dat file with notepad or notepad++. It had to do with notepad++ starter plugin associated with notepad++. It screwed up both notepad and notepad++. I had to install it and then uninstall it with the uninstall.bat file the installation created. I can open a .txt or .dat file by double clicking a file. The only way I can open up a .txt or .dat file with NotePad++ is opening NotePad++ and navigating to the file to open it, the right click menu way won't work for NotePad++ now hmm

I also switch the Procedure call to "Save As" after I added it to the Select/EndSelect as Case 4

I will probably have to add a comma delimiter so that the load from file option will work when I add it.

I still don't understand this Define. Periods between words confuses me. I see them a lot in complex arrays ugh
Define EnterInfo.EnterInfo_Structure

Code: Select all

EnableExplicit

; enumerated constants
Enumeration Window
  #Window_Main
  #Window_EnterInfo
  #Window_Help
EndEnumeration

Enumeration File
  #File
  #File_1
EndEnumeration

Enumeration gadget
  #gadget
  #gadget_1
  #Icongadget
  #IconGadget_1
  #ImageGadgetEnterInfo
  #ImageGadget_1
  #ButtonAddMed ; Add Med button #Window
  #ButtonOkEnterInfo ; Ok button #Window_1
  #StringGadget_MedName
  #StringGadget_DoseStrength
  #StringGadget_NumDoses
  #StringGadget_IntendedUse
  #StringGadget_MedUse
  ;#StringGadget_5
EndEnumeration

Enumeration Toolbar
  #TOOLBAR
EndEnumeration

Enumeration StatusBar
  #StatusBar
EndEnumeration



#LVM_GETHEADER = #LVM_FIRST + 31 

Structure EnterInfo_Structure
  Med$
  DoseStrength$
  NumDoses$
  IntendedUse$
  MedUses$
  Med.i
  DoseStrength.i
  NumDoses.i
  IntendedUse.i
  MedUses.i
EndStructure

; Globals 
Global oldListIconCallback, hHeader, redbrush, bluebrush 
redbrush=CreateSolidBrush_($9D9E9F)
bluebrush=CreateSolidBrush_($9D9E9F)


; Proc for subclassed ListIconGadget 
Procedure SubclassedListIcon(hwnd, msg, wparam, lparam) 
  
  Protected hdi.hd_item, result.i, *pnmh.NMHDR, *pnmcd.NMCUSTOMDRAW, text$
  
  
  result = CallWindowProc_(oldListIconCallback, hwnd, msg, wparam, lparam) 
  Select msg 
    Case #WM_NOTIFY 
      *pnmh = lparam
      ;--> Get handle to ListIcon header control 
      If *pnmh\code = #NM_CUSTOMDRAW
        *pnmcd = lparam 
        ;--> Determine drawing stage 
        Select *pnmcd\dwDrawStage 
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
            ;Get header text.
            text$=Space(100)
            hdi\mask = #HDI_TEXT
            hdi\psztext = @text$
            hdi\cchtextmax = Len(text$)
            SendMessage_(hHeader, #HDM_GETITEM,*pnmcd\dwItemSpec,hdi)
            ;Check button state.
            If *pnmcd\uItemState & #CDIS_SELECTED
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
              ;Offset text because of the selected button.
              InflateRect_(*pnmcd\rc,-1,-1)
            Else
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH)
            EndIf
            ;Draw background.
            ;Here we alternate red text on blue background.
            InflateRect_(*pnmcd\rc,-1,-1)
            SetBkMode_(*pnmcd\hdc,#TRANSPARENT) 
            If *pnmcd\dwItemSpec&1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, redbrush)
              SetTextColor_(*pnmcd\hdc, $A0222222) 
            Else
              FillRect_(*pnmcd\hdc, *pnmcd\rc, bluebrush)
              SetTextColor_(*pnmcd\hdc, $A0222222) 
            EndIf
            DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_CENTER | #DT_VCENTER | #DT_END_ELLIPSIS)
            result = #CDRF_SKIPDEFAULT
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure

; save routine
Procedure SaveMedList()
  Protected Input$, text$
  Protected.i lastItem, item, column
  Input$ = SaveFileRequester("Meds Companion","Untitled.txt", "Text (*.txt)|*.txt;*.bat|*.txt;*.dat|All files (*.*)|*.*", 0)
  If Input$
    lastItem = CountGadgetItems(#Icongadget)
    If CreateFile(0, Input$)
      For item = 0 To lastItem - 1
        text$ = GetGadgetItemText(#Icongadget, item, 0)
        For column = 0 To 5
          text$ + " " + GetGadgetItemText(#Icongadget, item, column)
        Next column
        WriteStringN(0, text$, #PB_Ascii)
      Next item
      CloseFile(0)
    EndIf
  EndIf
EndProcedure


;---------------------------------------------------------------------
; enter medication procedure
Procedure OpenEnterInfo(*Info.EnterInfo_Structure)
  
  Protected Tmp.i
  
  OpenWindow(#Window_EnterInfo, 0, 0, 290, 280, "Meds Companion", #PB_Window_SystemMenu | #PB_Window_WindowCentered, WindowID(#Window_Main))
  SetWindowColor(#Window_EnterInfo, $D5D5D5)
  
  LoadFont(0, "Arial", 10)
  SetGadgetFont(#PB_Default, FontID(0))
  
  Tmp = TextGadget(#PB_Any, 5, 20, 250, 20, "Enter medication name")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_MedName, 5, 37, 250, 20, *Info\Med$)
  SetGadgetText(#StringGadget_MedName, "")
  
  Tmp = TextGadget(#PB_Any, 5, 65, 250, 20,  "Enter dosage strength")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_DoseStrength, 5, 83, 250, 20, *Info\DoseStrength$)
  SetGadgetText(#StringGadget_DoseStrength, "")
  
  Tmp = TextGadget(#PB_Any, 5, 110, 250, 20,  "Enter number of daily doses")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_NumDoses, 5, 129, 250, 20, *Info\NumDoses$)
  SetGadgetText(#StringGadget_NumDoses, "")
  
  Tmp = TextGadget(#PB_Any, 5, 152, 250, 20,  "Enter what medication is proscribed for")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_IntendedUse, 5, 170, 250, 20, *Info\IntendedUse$)
  SetGadgetText(#StringGadget_IntendedUse, "")
  
  Tmp = TextGadget(#PB_Any, 5, 195, 250, 20,  " Enter medication uses")
  SetGadgetColor(Tmp, #PB_Gadget_BackColor, $D5D5D5)
  StringGadget(#StringGadget_MedUse, 5, 214, 250, 20, *Info\MedUses$)
  SetActiveGadget(#StringGadget_MedName)
  SetGadgetText(#StringGadget_MedUse, "")
  
  ButtonGadget(#ButtonOkEnterInfo, 196, 245, 60, 25, "Ok")
  
  ;SetGadgetItemColor(#Icongadget, -1, #PB_Gadget_FrontColor, $A0AA2222, #PB_All)
  
  SetGadgetFont(#PB_Default, #PB_Default)
  
EndProcedure
;--------------------------------------------------------------------------------
; help file procedure
Procedure MedsCompHelp()
  
  Protected wFlags.i
  
  ; window constant settings
  wFlags = #PB_Window_SystemMenu | #PB_Window_WindowCentered |#PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget
  OpenWindow(#Window_Help, 0, 0, 950, 550, "Meds Companion help", wFlags, WindowID(#Window_Main))
  
  ; open a window to use for the program
  ;OpenHelp("Help.chm", "Help\Help.html")
  
EndProcedure
;------------------------------------------------------------------------------------
;-Main

Define.i wFlags, LFlags, Event, Exit, lastItem, item, column
Define Input$, a$, text$
Define EnterInfo.EnterInfo_Structure

; window constant settings
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget
; open a window to use for the program
If OpenWindow(#Window_Main, 0, 0, 1024, 768, "Meds Companion", wFlags)
  
  LoadFont(0, "Arial", 11, #PB_Font_Bold)
  
  ; toolbar menu
  If CreateMenu(0, WindowID(#Window_Main))
    MenuTitle("Open")
    MenuItem(1, "New List")
    MenuItem(2, "Open List")
    OpenSubMenu("Recent Files")
    CloseSubMenu()
    MenuItem(3, "Save"   +Chr(9)+"Ctrl+S")
    MenuItem(4, "Save as"+Chr(9)+"Ctrl+A")
    MenuItem(5, "Close"  +Chr(9)+"Ctrl+C")
    MenuItem(6, "Quit")
    MenuTitle("Help")
    MenuItem(7, "Meds Companion help")
    MenuItem(8, "Online Medication lookup")
  EndIf
  ; create form to show and use information
  LFlags = #PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines | #PB_ListIcon_MultiSelect | #LVS_NOSORTHEADER
  
  ; create gadget for medication list
  ListIconGadget(#Icongadget, 1, 25, 1022, 700, "MEDICATION NAME", 150, LFlags)
  hHeader = SendMessage_(GadgetID(#Icongadget), #LVM_GETHEADER, 0, 0)
  ;Subclass ListIcon so we can customdraw the header text 
  oldListIconCallback = SetWindowLong_(GadgetID(#Icongadget), #GWL_WNDPROC, @SubclassedListIcon()) 
  ;set the gadget font, back color And line color
  SetGadgetFont(#Icongadget, FontID(0))
  SetGadgetColor(#Icongadget, #PB_Gadget_BackColor, $D0CDCECE)
  ;SetGadgetColor(#gadget, #PB_Gadget_LineColor, $D048494A)  
  ; add medication button
  ButtonGadget(#ButtonAddMed, 10, 0, 100, 25, "Add Med")
  
  ; add category columns
  AddGadgetColumn(#Icongadget, 1, "DOSAGE (mg)", 120)
  AddGadgetColumn(#Icongadget, 2, "DAILY DOSES", 110)
  AddGadgetColumn(#Icongadget, 3, "PRESCRIBED FOR", 240)
  AddGadgetColumn(#Icongadget, 4, "Medication Uses", 397)
  
  ; create statusbar at the bottom
  If CreateStatusBar(#StatusBar, WindowID(#Window_Main))
    AddStatusBarField(155) ; total medications
    AddStatusBarField(83)  ; blank and borderless
    AddStatusBarField(90)  ; doses daily(Either total doses or total of the highlighted medication in the list)
    AddStatusBarField(130) ; 
    AddStatusBarField(497)
  EndIf
  
  ; statusbar field text
  StatusBarText(#StatusBar, 0, "Total Medications", #PB_StatusBar_BorderLess)
  StatusBarText(#StatusBar, 1, "", #PB_StatusBar_Center | #PB_StatusBar_BorderLess)
  StatusBarText(#StatusBar, 2, "Total Daily Doses", #PB_StatusBar_Center | #PB_StatusBar_BorderLess) 
  FreeFont(0)
  
  ;- main program loop  
  Repeat
    Event = WaitWindowEvent()
    
    Select EventWindow()
      Case #Window_Main
        Select Event
          Case #PB_Event_CloseWindow
            CloseWindow(#Window_Main)
            Exit = #True
            
          Case #PB_Event_Menu
            Select EventMenu()
              Case 1 ; start new medication list
                ClearGadgetItems(#Icongadget)
                
              Case 2 ; load saved medication list
                Input$ = InputRequester("Meds Companion", "Enter saved list name", "")
                If Input$ = ""
                  MessageRequester("Meds Companion", Input$)
                Else
                  a$ = "The requester was canceled or there was nothing entered."
                  MessageRequester("Information", a$, 0)
                EndIf
                ; save current medication list
                
              Case 3
                
              Case 4
                SaveMedList()
                ; quit program  
              Case 6
                Exit = #True
                
              Case 7
                MedsCompHelp()          
                
            EndSelect
            
          Case #PB_Event_Gadget
            Select EventGadget()
              Case #ButtonAddMed
                OpenEnterInfo(@EnterInfo)
            EndSelect
        EndSelect
        
      Case #Window_EnterInfo
        Select Event
          Case #PB_Event_CloseWindow
            CloseWindow(#Window_EnterInfo)
            SetActiveWindow(#Window_Main)
            
          Case #PB_Event_Gadget
            Select EventGadget()
              Case #ButtonOkEnterInfo
                EnterInfo\Med$ = GetGadgetText(#StringGadget_MedName)
                EnterInfo\DoseStrength$ = GetGadgetText(#StringGadget_DoseStrength)
                EnterInfo\NumDoses$ = GetGadgetText(#StringGadget_NumDoses)
                EnterInfo\IntendedUse$ = GetGadgetText(#StringGadget_IntendedUse)
                EnterInfo\MedUses$ = GetGadgetText(#StringGadget_MedUse)
                AddGadgetItem(#Icongadget, -1, EnterInfo\Med$ + #LF$ + EnterInfo\DoseStrength$ + " mg" + #LF$ + EnterInfo\NumDoses$ + #LF$ + EnterInfo\IntendedUse$ + #LF$ + EnterInfo\MedUses$)
                PostEvent(#PB_Event_CloseWindow, #Window_EnterInfo, 0)
                
            EndSelect
        EndSelect
        
      Case #Window_Help
        Select Event
          Case #PB_Event_CloseWindow
            CloseWindow(#Window_Help)
            SetActiveWindow(#Window_Main)
        EndSelect
        
    EndSelect
    
  Until Exit
EndIf
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
Post Reply