API Question. #CBN_SELCHANGE and #EN_CHANGE handling

Just starting out? Need help? Post your questions and find answers here.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

API Question. #CBN_SELCHANGE and #EN_CHANGE handling

Post by Fangbeast »

I have a callback working on a ListIconGadget with a hidden combobox and a hidden stringgadget.

The combobox detection and change (The #CBN_SELCHANGE section) works fine as it should. Master srod designed it:):)

I've added the stringgadget and it sort of works. The #EN_CHANGE is being detected and the stringbox activated but it closes immediately after one character.

I suspect this is because I don't understand what (wParam >> 16) & $ffff does and I have the #EN_CHANGE in the wrong place but I frankly (even Georgely!!) don't understand this bit of code so cannot fix it.

Anyone have any ideas please?

Code: Select all

Procedure.l ListIconECallBack(hWnd, uMsg, wParam, lParam)  ; The following callback allows a listicon control to be subclassed.
  Protected Result
  Select uMsg
    Case #WM_COMMAND                ; This is how the CBN_SELCHANGE message is sent.
      Select (wParam >> 16) & $ffff ; This contains the notification code.
        ;-----------------------------------------------------------------
        Case #CBN_SELCHANGE
          MapItem.l = GetGadgetState(#Gadget_exportaddress_mapbox)
          NewText.s = GetGadgetItemText(#Gadget_exportaddress_mapbox, MapItem.l, 0)
          SetGadgetItemText(#Gadget_exportaddress_tables, GetGadgetState(#Gadget_exportaddress_tables), NewText, 1)
          If Newtext.s <> "-Empty-"
            SetGadgetItemText(#Gadget_exportaddress_tables, GetGadgetState(#Gadget_exportaddress_tables), Str(MapItem.l + 1), 2)
          EndIf
          HideGadget(#Gadget_exportaddress_mapbox, 1)
          ;---------------------------------------------------------------
        Case #EN_CHANGE
          NewText.s = GetGadgetText(#Gadget_exportaddress_stringbox)       ; Get the text from the string box
          SetGadgetItemText(#Gadget_exportaddress_tables, GetGadgetState(#Gadget_exportaddress_tables), NewText, 0)
          HideGadget(#Gadget_exportaddress_stringbox, 1)                   ; Hide the gadget again
          ;---------------------------------------------------------------
      EndSelect
  EndSelect
  Result = CallWindowProc_(OldListEProc, hWnd, uMsg, wParam, lParam)
  ProcedureReturn Result
EndProcedure
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I suspect this is because I don't understand what (wParam >> 16) & $ffff does and I have the #EN_CHANGE in the wrong place but I frankly (even Georgely!!) don't understand this bit of code so cannot fix it.
Fangs, the #WM_COMMAND message is sent to the parent window of the relevant control, in this case the parent of the String Gadget which is the ListIcon; so everything looks fine. When the #WM_COMMAND message fires, it places the code for the particular notification in the high order word of the wParam parameter, i.e. in the last 16 bits. To get at this code, we first shift these 16 bits into the low order word (by using wParam >>16) and then to extract these 16 bits, perform a bitwise AND with the binary number %1111111111111111 (or $ffff in hexadecimal). We can then test this code for #CBN_SELCHANGE or #EN_CHANGE etc.

As for your string gadget closing, your code suggests that it is simply being hidden. The #EN_CHANGE message fires whenever the string gadget thinks that the user has changed the contents. This means that whenever a key is pressed, the message fires. Thus, because of the command HideGadget(#Gadget_exportaddress_stringbox, 1), your string gadget is being hidden after every key press!

Hope this helps.
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Ouch!

Post by Fangbeast »

"Fangs, the #WM_COMMAND message is sent to the parent window of the relevant control, in this case the parent of the String Gadget which is the ListIcon; so everything looks fine. When the #WM_COMMAND message fires, it places the code for the particular notification in the high order word of the wParam parameter, i.e. in the last 16 bits. To get at this code, we first shift these 16 bits into the low order word (by using wParam >>16) and then to extract these 16 bits, perform a bitwise AND with the binary number %1111111111111111 (or $ffff in hexadecimal). We can then test this code for #CBN_SELCHANGE or #EN_CHANGE etc."

I didn't really understand that but I can work with it:):)

"As for your string gadget closing, your code suggests that it is simply being hidden. The #EN_CHANGE message fires whenever the string gadget thinks that the user has changed the contents. This means that whenever a key is pressed, the message fires. Thus, because of the command HideGadget(#Gadget_exportaddress_stringbox, 1), your string gadget is being hidden after every key press!"

Ouch, that was dumb of me. Hiding the string gadget is taken care of elsewhere and I was hiding it prematurely. Oh well, live and learn.

Do you know what events are fired off by calendargadgets as I want to add them next?

Thanks for all your help, it has been invaluable.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Afraid I've never used a calendar gadget. It doesn't appear to be a native Window's control (I could be wrong there) and so there's not much info around. If it isn't a native Window's control, then you'd need to find which control (if any) it is based upon before you can identify the messages etc. It might simply be painted directly onto a static control, or some other container, or even a subclassed ListViewGadget etc.
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Thanks for that.

Post by Fangbeast »

srod, is there anything I can do for you to thank you for all your help?

P.s. Latest changes are working great, new release for address book shortly with output mapping now. Damn it, now I have to write a help file:(
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

If I gave a quid to everyone who's helped me with PB and Win API or whose code I've swiped and studied to death, then I'd owe some horrendous amount. Sparkie would be a rich man, El-choni would probably get my house, ... :lol:

Like everyone on these forums, I'm just glad to help and give something back.
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

srod wrote:If I gave a quid to everyone who's helped me with PB and Win API or whose code I've swiped and studied to death, then I'd owe some horrendous amount. Sparkie would be a rich man, El-choni would probably get my house, ... :lol:

Like everyone on these forums, I'm just glad to help and give something back.
At that rate, El would own my first born child, Fred my cats, Frek, Rings and a few others my house and computer etc....The list goes on and on
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

srod wrote:Afraid I've never used a calendar gadget. It doesn't appear to be a native Window's control (I could be wrong there) and so there's not much info around. If it isn't a native Window's control, then you'd need to find which control (if any) it is based upon before you can identify the messages etc. It might simply be painted directly onto a static control, or some other container, or even a subclassed ListViewGadget etc.
There's a month calendar control - "SysMonthCal32" if you're using CreateWindow_() or CreateWindowEx_() to create it from scratch rather than using internal PB stuff.

http://msdn.microsoft.com/library/defau ... eflist.asp

That should get you the list of messages and notifications available for it. To be on the safe side, you may want to run GetClassName_() on the PB calendar gadget just to make sure it's the same one.

Code: Select all

Procedure.b GetGadgetType(Handle.l)
   ; Return the gadget type based on the classname used in CreateWindowEx_()
   HoldString.s
   ; This will store the length of the wide character string, in characters.
   lCount.l
   ; Used to store the number of character copied.
   HoldString = Space(255)
   ; Allocate size for our string.
   GetClassName_(Handle, @HoldString, 255)
   ; Call our function to retrieve the classname.
   ProcedureReturn HoldString
   ;
EndProcedure
Should tell you what it is. I messed with calendar gadgets a little bit and I think it only returned one event. I suspect the PB version might be an edit control with this calendar attached to it. Not sure.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> I've never used a calendar gadget. It doesn't appear to be a native Window's control

The CalendarGadget calls the native Windows control called "SysMonthCal32".
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Fangbeast wrote:Do you know what events are fired off by calendargadgets as I want to add them next?
You can use Win API for a couple events...

Code: Select all

#MCN_SELCHANGE = #MCN_FIRST + 1
#MCN_SELECT = #MCN_FIRST + 4

Procedure WinCallback(hwnd, msg, wparam, lparam)
  result = #PB_ProcessPureBasicEvents
  Select msg
    Case #WM_NOTIFY
      *pnmh.NMHDR = lparam
      If *pnmh\hwndFrom = GadgetID(0)
        Select *pnmh\code
          Case #MCN_SELCHANGE
            selDate = GetGadgetState(0)
            selDate$ = FormatDate("%yyyy/%mm/%dd", selDate)
            SetGadgetText(1, "Selected Month has changed to" + #CRLF$ + selDate$)
          Case #MCN_SELECT
            selDate = GetGadgetState(0)
            selDate$ = FormatDate("%yyyy/%mm/%dd", selDate)
            SetGadgetText(1, "Selected Day has changed to" + #CRLF$ + selDate$)
        EndSelect
      EndIf
  EndSelect
  ProcedureReturn result
EndProcedure
      
If OpenWindow(0, 0, 0, 220, 280, #PB_Window_SystemMenu|#PB_Window_ScreenCentered,"CalendarGadget()")
  If CreateGadgetList(WindowID())
    CalendarGadget(0, 10, 10, 200, 180)
    TextGadget(1, 10, 200, 200, 50, "")
    SetWindowCallback(@WinCallback())
    Repeat
      event = WaitWindowEvent()
    Until event = #PB_Event_CloseWindow
  EndIf
EndIf
@srod: Thanks for the thought of making me a rich man but your quid don't spend too well over here. :mrgreen:
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Flamin' heck, some people are just dead set legends!

Post by Fangbeast »

Like the subject says. And you aren't even dead yet!!!

/me bows low to the great sparkie of codedom.

That makes three geniuses in the forum (or should that be geniiiiiii??). srod, xombie and you.

I think we should set concrete boxes around all of you so you will all be safe MWUAHAHAHA :lol: :lol: :lol:

/me wanders off to take his weird pills

Now, do you have one for the dategadget? The one I need:):):)

Never mind.I think it's this one #DTN_DATETIMECHANGE
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Thanks sparkie (and all others)

Post by Fangbeast »

This is the working routine (testbed). Now that I know where to look, I am able to build on it.

Code: Select all


#DTN_DATETIMECHANGE = #DTN_FIRST + 1


Procedure WinCallback(hwnd, msg, wparam, lparam)
  result = #PB_ProcessPureBasicEvents
  Select msg
    Case #WM_NOTIFY
      *pnmh.NMHDR = lparam
      If *pnmh\hwndFrom = GadgetID(0)
        Select *pnmh\code
          Case #DTN_DATETIMECHANGE
            selDate = GetGadgetState(0)
            selDate$ = FormatDate("%dd/%mm/%yyyy", selDate)
            SetGadgetText(1, "Selected Month has changed to" + #CRLF$ + selDate$)
        EndSelect
      EndIf
  EndSelect
  ProcedureReturn result
EndProcedure
     
If OpenWindow(0, 0, 0, 220, 280, #PB_Window_SystemMenu|#PB_Window_ScreenCentered,"CalendarGadget()")
  If CreateGadgetList(WindowID())
    DateGadget(0, 10, 10, 200, 25)
    TextGadget(1, 10, 200, 200, 50, "")
    SetWindowCallback(@WinCallback())
    Repeat
      event = WaitWindowEvent()
    Until event = #PB_Event_CloseWindow
  EndIf
EndIf 
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

The rest of the datepicker messages

Post by Fangbeast »

In case anyone wants them:

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

Sent by a date and time picker (DTP) control when the user closes the drop-down month calendar. The month calendar is closed when the user chooses a date from the month calendar or clicks the drop-down arrow while the calendar is open.

DTN_CLOSEUP = DTN_FIRST + 7

Sent by a date and time picker (DTP) control whenever a change occurs. This notification message is sent in the form of a WM_NOTIFY message.

DTN_DATETIMECHANGE = DTN_FIRST + 1

Sent by a date and time picker (DTP) control when the user activates the drop-down month calendar.

DTN_DROPDOWN = DTN_FIRST + 6

Sent by a date and time picker (DTP) control to request text to be displayed in a callback field. This notification message is sent in the form of a WM_NOTIFY message.

DTN_FORMAT
DTN_FORMATA = DTN_FIRST + 4
DTN_FORMATW = DTN_FIRST + 17

Sent by a date and time picker (DTP) control to retrieve the maximum allowable size of the string that will be displayed in a callback field. This notification message is sent in the form of a WM_NOTIFY message.

DTN_FORMATQUERY
DTN_FORMATQUERYA = DTN_FIRST + 5
DTN_FORMATQUERYW = DTN_FIRST + 18

Sent by a date and time picker (DTP) control when a user finishes editing a string in the control. This notification message is only sent by DTP controls that are set to the DTS_APPCANPARSE style. This message is sent in the form of a WM_NOTIFY message.

DTN_USERSTRING
DTN_USERSTRINGA = DTN_FIRST + 2
DTN_USERSTRINGW = DTN_FIRST + 15

Sent by a date and time picker (DTP) control when the user types in a callback field. This message is sent in the form of a WM_NOTIFY message.

DTN_WMKEYDOWN
DTN_WMKEYDOWNA = DTN_FIRST + 3
DTN_WMKEYDOWNW = DTN_FIRST + 16

Notifies a date and time picker control's parent window that the control has lost the input focus. NM_KILLFOCUS (date time) is sent in the form of a WM_NOTIFY message.

NM_KILLFOCUS = NM_FIRST-8

Notifies a date and time picker control's parent window that the control has received the input focus. NM_SETFOCUS (date time) is sent in the form of a WM_NOTIFY message.

NM_SETFOCUS = NM_FIRST-7

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

MSDN page reference:

http://msdn.microsoft.com/library/defau ... change.asp
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Thanks Fangles, but if it's all the same to you, I prefer to remain a living mortal for the time being. ;)

And as for being stuck inside a wall of concrete boxes, well (no offense to srod and Xombie) unless one of them is of the female gender, I'll take a pass on that too. :razz:

I see you beat me to the DateGadget messages. :) This one can also be done without a callback due to the fact that, unlike the CalendarGadget, the DateGadget sends a #PB_EventGadget when a change occurs. Just adjust the mask$ to remove the time if it's not needed. ;)

Code: Select all

If OpenWindow(0, 0, 0, 220, 280, #PB_Window_SystemMenu|#PB_Window_ScreenCentered,"CalendarGadget()")
  If CreateGadgetList(WindowID())
    DateGadget(1, 10, 10, 180, 25, "Date: %mm/%dd/%yyyy Time: %hh:%ii")
    TextGadget(2, 10, 200, 200, 50, "")
    Repeat
      event = WaitWindowEvent()
      If event = #PB_EventGadget And EventGadgetID() = 1
        selDateTime = GetGadgetState(1)
        selDateTime$ = FormatDate("%yyyy/%mm/%dd  %hh:%ii", selDateTime)
        SetGadgetText(2, "DateGadget has changed to" + #CRLF$ + selDateTime$)
      EndIf
    Until event = #PB_Event_CloseWindow
  EndIf
EndIf
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

What can I say???

Post by Fangbeast »

"Thanks Fangles, but if it's all the same to you, I prefer to remain a living mortal for the time being"

Why set a precendent?? Oh, okay. You win.

"And as for being stuck inside a wall of concrete boxes, well (no offense to srod and Xombie) unless one of them is of the female gender, I'll take a pass on that too"

I've heard rumours about the two of them but diodn't want to say anything.

"This one can also be done without a callback due to the fact that, unlike the CalendarGadget, the DateGadget sends a #PB_EventGadget when a change occurs"

I knew about this one. But for the context in which it will sit, it needs to be an API solution. Easier to integrate it with the existing 2 gadgets and the auto-resize routines.

Will release an update to appointment minder soon illustrating the point.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Post Reply