MultiLine PushButton

Started by JTaylor, January 16, 2017, 07:09:20 AM

Previous topic - Next topic

JTaylor

Thanks to IfICantByte for the MultiLine Pushbutton Solution....Two things on this front. 

The first set of code demonstrates how doing this causes the ability to Color the buttons, Set Text, It not be Flat, etc. to go away.  Would I be correct in assuming that I would need to reproduce the LPITEMDRAWSTRUCT and apply it to do such things, assuming this is doable?  Sample Code?   :)

The Second is an example for the Tech Database which could be appended to the other post and which does the same thing as the other except using the latest version of WinBatch.  This process has gotten much easier over the years and thought updated code might be helpful to someone.

Thanks.

Jim

Code (winbatch) Select

WinHide("")

Home_Path = DirScript()
DirChange(Home_Path)
GoSub Load_Routines

OPSETUPFormat=`WWWDLGED,6.2`

OPSETUPCaption=`OP Setup`
OPSETUPX=-01
OPSETUPY=-01
OPSETUPWidth=258
OPSETUPHeight=162
OPSETUPNumControls=002
OPSETUPProcedure=`OPSETUP_Sub`
OPSETUPFont=`DEFAULT`
OPSETUPTextColor=`DEFAULT`
OPSETUPBackground=`DEFAULT,64|0|64`
OPSETUPConfig=2

OPSETUP001=`221,003,028,012,PUSHBUTTON,"pb_OPS_Exit",DEFAULT,"E&xit",1,9,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
OPSETUP002=`011,005,074,020,CHECKBOX,"cb_OPS_cb",cb,"PushButton With Multiple Lines",1,130,DEFAULT,"Microsoft Sans Serif|6656|40|34","255|255|255",DEFAULT`

ButtonPushed=Dialog("OPSETUP")


Exit

:Load_Routines


#DefineFunction CBox2MLB(hDialog, nControl)

  ; Developer: IFICANTBYTE
  ; CBox2MLButton - Give a Checkbox in a WinBatch Dialog the correct style to display itself as a button with multiple lines of text
  ; Don't use this on other types of controls or you will encounter strange results!

  ; hDialog  - window handle to WIL dialog
  ; nControl - template position number of dialog control

  BS_PUSHLIKE  = 4096   ; Not always necessary but found in one project with a LOT of buttons that it was necessary.  Never figured out why.
  BS_OWNERDRAW = 11     ; Required to Color PushButton
  BS_MULTILINE = 8192
  BS_CHECKBOX = 2
  ;Some other ButtonStyles you could logically OR to align the text on the button
  BS_BOTTOM = 2048
  BS_CENTER = 768
  BS_LEFT = 256
  BS_RIGHT = 512
  BS_TOP = 1024
  BS_VCENTER = 3072
;BS_RADIOBUTTON = 4 - just for reference - you could probably adapt this UDF to do the same with radio buttons
  hUser32 = DllLoad(DirWindows(1):"User32.dll")
  CtrlStyle = DllCall(hUser32, long:"GetWindowLongA", long:nControl, long:-16)
  DllCall(hUser32, long:"SetWindowLongA", long:nControl, long:-16, long:(CtrlStyle^BS_CHECKBOX)|BS_MULTILINE); take away checkbox style and add multiline
  DllFree(hUser32)

#EndFunction


#DefineSubRoutine OPSETUP_Sub(OPS_Handle,DMsg,DCID,DEInfo,ChangeInfo)

Switch (DMsg)
    Case @deInit
    DialogProcOptions(OPS_Handle, @dePbPush,1)                            ; Pushbutton/PictureButton.
    DialogProcOptions(OPS_Handle, @deCbCheck,1)                           ; CheckBox.
       
    DialogControlSet(OPS_Handle, "cb_OPS_cb", @dcBackColor, "126|133|175")

    hwnd = DialogControlGet(OPS_Handle,"cb_OPS_cb",@dchWnd)
    CBox2MLB(OPS_Handle,hwnd)

    DialogControlSet(OPS_Handle, "cb_OPS_cb", @dcBackColor, "126|133|175")

    DialogControlSet(OPS_Handle, "pb_OPS_Exit", @dcBackColor, "6|133|175")

    DialogProcOptions(OPS_Handle, @deTimer,0)
    Break
  Case @deTimer

    Break
  Case @deClose
    Return 9
    Break
  Case @deCbCheck
    Switch(DialogProcOptions(OPS_Handle,@dpoCtlNumber,DCID))
      Case DialogProcOptions(OPS_Handle,@dpoCtlNumber,"cb_OPS_cb")
        cb = DialogControlGet(OPS_Handle,"cb_OPS_cb",@dcCheck)
        Message("YO","What's Up?")
        Break
    EndSwitch
    Break
  Case @dePbPush
    Switch(DialogProcOptions(OPS_Handle,@dpoCtlNumber,DCID))
      Case DialogProcOptions(OPS_Handle,@dpoCtlNumber,"pb_OPS_Exit")
        button_text = DialogControlGet(OPS_Handle,"pb_OPS_Exit",@dcTitle)
        Return -1
        Break
    EndSwitch
    Break
EndSwitch
Return -2

#EndSubRoutine

Return



Sample for Tech Database

Code (winbatch) Select

WinHide("")

Home_Path = DirScript()
DirChange(Home_Path)
GoSub Load_Routines

OPSETUPFormat=`WWWDLGED,6.2`

OPSETUPCaption=`OP Setup`
OPSETUPX=-01
OPSETUPY=-01
OPSETUPWidth=258
OPSETUPHeight=162
OPSETUPNumControls=002
OPSETUPProcedure=`OPSETUP_Sub`
OPSETUPFont=`DEFAULT`
OPSETUPTextColor=`DEFAULT`
OPSETUPBackground=`DEFAULT,64|0|64`
OPSETUPConfig=2

OPSETUP001=`221,003,028,012,PUSHBUTTON,"pb_OPS_Exit",DEFAULT,"E&xit",1,9,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
OPSETUP002=`011,005,074,020,CHECKBOX,"cb_OPS_cb",cb,"PushButton With Multiple Lines",1,130,DEFAULT,"Microsoft Sans Serif|6656|40|34","255|255|255",DEFAULT`

ButtonPushed=Dialog("OPSETUP")


Exit

:Load_Routines


#DefineFunction CBox2MLB(hDialog, nControl)

  ; Developer: IFICANTBYTE
  ; CBox2MLButton - Give a Checkbox in a WinBatch Dialog the correct style to display itself as a button with multiple lines of text
  ; Don't use this on other types of controls or you will encounter strange results!

  ; hDialog  - window handle to WIL dialog
  ; nControl - template position number of dialog control

  BS_PUSHLIKE  = 4096   ; Not always necessary but found in one project with a LOT of buttons that it was necessary.  Never figured out why.
  BS_OWNERDRAW = 11     ; Required to Color PushButton
  BS_MULTILINE = 8192
  BS_CHECKBOX = 2
  ;Some other ButtonStyles you could logically OR to align the text on the button
  BS_BOTTOM = 2048
  BS_CENTER = 768
  BS_LEFT = 256
  BS_RIGHT = 512
  BS_TOP = 1024
  BS_VCENTER = 3072
;BS_RADIOBUTTON = 4 - just for reference - you could probably adapt this UDF to do the same with radio buttons
  hUser32 = DllLoad(DirWindows(1):"User32.dll")
  CtrlStyle = DllCall(hUser32, long:"GetWindowLongA", long:nControl, long:-16)
  DllCall(hUser32, long:"SetWindowLongA", long:nControl, long:-16, long:(CtrlStyle^BS_CHECKBOX)|BS_MULTILINE); take away checkbox style and add multiline
  DllFree(hUser32)

#EndFunction


#DefineSubRoutine OPSETUP_Sub(OPS_Handle,DMsg,DCID,DEInfo,ChangeInfo)

Switch (DMsg)
    Case @deInit
    DialogProcOptions(OPS_Handle, @dePbPush,1)                            ; Pushbutton/PictureButton.
    DialogProcOptions(OPS_Handle, @deCbCheck,1)                           ; CheckBox.
       
    hwnd = DialogControlGet(OPS_Handle,"cb_OPS_cb",@dchWnd)
    CBox2MLB(OPS_Handle,hwnd)
    Break
  Case @deCbCheck
    Switch(DialogProcOptions(OPS_Handle,@dpoCtlNumber,DCID))
      Case DialogProcOptions(OPS_Handle,@dpoCtlNumber,"cb_OPS_cb")
        cb = DialogControlGet(OPS_Handle,"cb_OPS_cb",@dcCheck)
        Message("YO","What's Up?")
        Break
    EndSwitch
    Break
  Case @dePbPush
    Switch(DialogProcOptions(OPS_Handle,@dpoCtlNumber,DCID))
      Case DialogProcOptions(OPS_Handle,@dpoCtlNumber,"pb_OPS_Exit")
        button_text = DialogControlGet(OPS_Handle,"pb_OPS_Exit",@dcTitle)
        Return -1
        Break
    EndSwitch
    Break
EndSwitch
Return -2

#EndSubRoutine

Return



td

The Windows operating system implements push buttons differently than other buttons and other common/User control windows.  For this reason WIL dialog push buttons are mostly implemented internally with little reliance on the operating system's implementation.  WIL dialog push buttons are not owner drawn in the usual Windows sense.  They are owner implemented.

On the other hand, the OS provides a fairly straight forward way to modify the appearance  of check boxes, static and edit boxes by sending a specific message to a dialog's window procedure.  The dialog window procedure can respond to this message by passing back text and background color information to the OS.

However, multiline buttons would require creating an owner drawn control so that the dialog's windows procedure can provide color information to the OS when the OS reflects control draw messages back to the procedure.       
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

JTaylor