CWindow and default window styles

Started by Paul Squires, July 13, 2016, 11:16:03 PM

Previous topic - Next topic

Paul Squires

This has been driving me crazy for a while. In the past I would create controls and sometimes things didn't look right. Almost like a style was added such as a border. Well, today I started work on an ownerdrawn listbox and it kept displaying a border no matter I tried. I started to pull my hair out until I started looking at the CWindow code in AddControl. The logic is to create default styles whenever dwStyle or dwExStyle are zero. This was the problem.

For the Listbox, i was passing WS_EX_LEFT Or WS_EX_RIGHTSCROLLBAR as the dwExStyle. I checked the MSN documentation and both of these styles have values of zero (they are default styles). So.... passing this to AddControl triggers dwExStyle to have WS_EX_CLIENTEDGE added. This is obviously not want I want.

My question, should we have default styles? Is this a way to appease the old PB'ers and the DDT mentality? Personally, I vote to get rid of them all.
Paul Squires
PlanetSquires Software

José Roca

#1
> Is this a way to appease the old PB'ers and the DDT mentality?

No, it is useful for not having to check the list of control styles each time that you want to create one and ascertain which ones are the appropriate for what you want, e.g. WS_CHILD OR WS_VISIBLE OR WS_VSCROLL OR WS_BORDER OR WS_TABSTOP OR CBS_DROPDOWN OR CBS_HASSTRINGS OR CBS_SORT. It saves you time and is also very helpful to beginners.

I wasn't aware of that problem with the extended styles, I'm sorry. I will look for a workaroumd.

José Roca

In PB I used -1, but if use a negative value in FB with these parameters, the controls aren't created, don't know why. Yet another bug? of this compiler.

As a workaround, I have done the following changes, that seem to work:


      DECLARE FUNCTION AddControl (BYREF wszClassName AS WSTRING, BYVAL hParent AS HWND = NULL, BYVAL cID AS INTEGER = 0, _
              BYREF wszTitle AS WSTRING = "", BYVAL x AS LONG = 0, BYVAL y AS LONG = 0, BYVAL nWidth AS LONG = 0, _
              BYVAL nHeight AS LONG = 0, BYVAL dwStyle_ AS LONG = -1, BYVAL dwExStyle_ AS LONG = -1, BYVAL lpParam AS LONG_PTR = 0, _
              BYVAL pWndProc AS WNDPROC = NULL, BYVAL uIdSubclass AS UINT_PTR = &HFFFFFFFF, BYVAL dwRefData AS DWORD_PTR = NULL) AS HWND



FUNCTION CWindow.AddControl ( _
   BYREF wszClassName AS WSTRING, _                       ' // Class name
   BYVAL hParent AS HWND = NULL, _                        ' // Parent window handle
   BYVAL cID AS INTEGER = 0, _                            ' // Control identifier
   BYREF wszTitle AS WSTRING = "", _                      ' // Control caption
   BYVAL x AS LONG = 0, _                                 ' // Horizontal position
   BYVAL y AS LONG = 0, _                                 ' // Vertical position
   BYVAL nWidth AS LONG = 0, _                            ' // Control width
   BYVAL nHeight AS LONG = 0, _                           ' // Control height
   BYVAL dwStyle_ AS LONG = -1, _                         ' // Control style
   BYVAL dwExStyle_ AS LONG = -1, _                       ' // Extended style
   BYVAL lpParam AS LONG_PTR = 0, _                       ' // Pointer to custom data
   BYVAL pWndProc AS WNDPROC = NULL, _                    ' // Address of the window callback procedure
   BYVAL uIdSubclass AS UINT_PTR = &HFFFFFFFF, _          ' // The subclass ID
   BYVAL dwRefData as DWORD_PTR = NULL _                  ' // Pointer to reference data
   ) AS HWND                                              ' // Control handle



   ' *** Workaround for what it looks like a bug of the compiler ***
   ' IF the default value of dwStyle or dwExStyle is a negative number,
   ' CreateWindowEx fails, even if the value is changed to a valid value.
   DIM dwStyle AS DWORD, dwExStyle AS DWORD
   IF dwStyle_ = -1 THEN dwStyle = 0 ELSE dwStyle = dwStyle_
   IF dwExStyle_ = -1 THEN dwExStyle = 0 ELSE dwExStyle = dwExStyle_


Paul Squires

Quote' IF the default value of dwStyle or dwExStyle is a negative number,
   ' CreateWindowEx fails, even if the value is changed to a valid value.

Not sure if this is right? Yes, CreateWindowEx does seem to fail if the value is -1 but if I do change it to a valid value (even zero) then it works. We are dealing with an unsigned long because of the DWORD so -1 becomes 4294967295.

In my few tests, all I had to do was change the default value in the parameter to be -1 instead of 0 and then change the logic in AddControl.

      Declare Function AddControl (ByRef wszClassName As WString, ByVal hParent As HWnd = Null, ByVal cID As Integer = 0, _
              ByRef wszTitle As WString = "", ByVal x As Long = 0, ByVal y As Long = 0, ByVal nWidth As Long = 0, _
              ByVal nHeight As Long = 0, ByVal dwStyle As DWORD = 0, ByVal dwExStyle As DWORD = -1, ByVal lpParam As LONG_PTR = 0, _
              ByVal pWndProc As WNDPROC = Null, ByVal uIdSubclass As UINT_PTR = &HFFFFFFFF, ByVal dwRefData As DWORD_PTR = Null) As HWnd

      Case "LISTBOX"
         ' Adds a list box to the window.
         If dwStyle = -1 Then dwStyle = WS_VISIBLE Or WS_HSCROLL Or WS_VSCROLL Or WS_BORDER Or WS_TABSTOP Or LBS_STANDARD Or LBS_HASSTRINGS Or LBS_SORT Or LBS_NOTIFY
         If dwExStyle = -1 Then dwExStyle = WS_EX_CLIENTEDGE

However, I do think that in this case it is better to use LONG instead of DWORD for the parameters (like you did in your workaround) just to sure that there isn't any weird numeric conversions screwing things up.

DWORD
A 32-bit unsigned integer. The range is 0 through 4294967295 decimal.
This type is declared in IntSafe.h as follows:
typedef unsigned long DWORD;
Paul Squires
PlanetSquires Software

José Roca

I was tired and couldn't think with clarity. It failed because I was changing the value of dwStyle, but not the one of dwExStyle to zero when it is not used.

For example, in:


      CASE "CUSTOMBUTTON", "OWNERDRAWBUTTON"
         ' Adds an ownerdraw button to the window.
         wsClassName = "Button"
         IF dwStyle = -1 THEN dwStyle = WS_VISIBLE OR WS_TABSTOP OR BS_OWNERDRAW



      CASE "CUSTOMBUTTON", "OWNERDRAWBUTTON"
         ' Adds an ownerdraw button to the window.
         wsClassName = "Button"
         IF dwStyle = -1 THEN dwStyle = WS_VISIBLE OR WS_TABSTOP OR BS_OWNERDRAW
         dwExStyle = 0


I need to set dwExStyle = 0; otherwise, CreateWindowEx fails.