Link to home
Start Free TrialLog in
Avatar of andla
andla

asked on

Using SetWindowLong (MSVC)

Why does the listbox freeze when i use LBS_SORT in SetWindowLong()?

      case IDC_BUTTON15:
            if(HIWORD(wp)==BN_CLICKED)
            {
      /*            LONG SetWindowLong(
    HWND hWnd,      // handle of window
    int nIndex,      // offset of value to set
    LONG dwNewLong       // new value*/


SetWindowLong((HWND)GetDlgItem(hw,IDC_LIST1),(int)GWL_STYLE,(LONG)LBS_SORT);
UpdateWindow(GetDlgItem(hw,IDC_LIST1));
            }
      break;

Your sincerely
Andla.
Avatar of nietod
nietod

One problem (maybe not the only one) is that you are setting only the LBS_SORT stile and clearing all the other styles.  That is probably not what you want.  There are styles there, like WS_CHILD at least, that you want to have remain.
What you should do is use GetWindowLong() to get the previou style and then set the LBS_SORT stile by ORing it into the old stule with the operator |.  Then set the window style to this new value.

Let me know if that doesn't clear it up.
For setting the style you can also try ModifyStyle MFC function which is handy

What nietod means is

DWORD dwStyle = GetWindowLong( HWND)GetDlgItem(hw,IDC_LIST1),GWL_STYLE) ;
dwStyle |= LBS_SORT ;
SetWindowLong((HWND)GetDlgItem(hw,IDC_LIST1),(int)GWL_STYLE,(LONG)dwStyle);


Avatar of andla

ASKER

Thanks for your answer :-), but my problem has changed from freezing to not sorting the items?? I was hoping that the items should sort up after i pressed the button.
Please help me!

Your sincerely
Andla
I beleive that changing the style will cause it to add new items sorted, not to sort what is there.  Remove the items and add them again and they will be sorted.
Avatar of andla

ASKER

Not my day to day. It doesn't work anything. Maybe to much coffee :-). Here is some code.
if(HIWORD(wp)==BN_CLICKED)
{
//SendDlgItemMessage(hw,IDC_LIST1,LB_RESETCONTENT,0,0);
DWORD dwStyle = GetWindowLong((HWND)GetDlgItem(hw,IDC_LIST1),GWL_STYLE) ;

dwStyle |= LBS_SORT ;

SetWindowLong((HWND)GetDlgItem(hw,IDC_LIST1),(int)GWL_STYLE,(LONG)dwStyle);
SendDlgItemMessage(hw,IDC_LIST1,LB_RESETCONTENT,0,0);
//UpdateWindow(GetDlgItem(hw,IDC_LIST1));
SendDlgItemMessage(hw,IDC_LIST1,LB_ADDSTRING,0,(LPARAM)"c");
SendDlgItemMessage(hw,IDC_LIST1,LB_ADDSTRING,0,(LPARAM)"b");
SendDlgItemMessage(hw,IDC_LIST1,LB_ADDSTRING,0,(LPARAM)"a");
}
break;
You are adding the strings to the wrong window.
LBS_SORT is not a style that can be changed at runtime.  You have to destroy the window and create a new one with the LBS_SORT flag set.
Opps, no you're not.  I though you were using SendMessage(), not SendDlgItemMessage(), and thus sending the add message to the dialog.  Sorry.

I don't see a problem.   I wonder why do you have so many casts? You should change the style to a LONG.  Then the only casts you need are the (LPARAM) when you add the strings.  Try to clean that up maybe somthing will turn up.
>> LBS_SORT is not a style that can be changed at runtime
Are you sure of that?  Most styles (maybe all) can be, and this would certainly be one that that would be desirable.

It that is the case, I guess you would have to resort to sorting it yourself, but I'm not convinced unless danny_pav has some documentation for that.
Avatar of andla

ASKER

Maybe something else is wrong. I have noticed that the HSCROLL doesent work from this resource:
    LISTBOX         IDC_LIST1,1,153,96,57,LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
                    WS_HSCROLL | WS_TABSTOP,WS_EX_STATICEDGE
If i understand it should letting me scroll horizontal if the string is longer than the listbox.? When i build my application, i'm not splitting the program over many files. Instead i'm using just one huge c file. I don't know if bugs appears if my .c file is to big? That could be the case why things don't work. (but i hope not)

Your sincerely
Andla.
>> I don't know if bugs appears if my .c file is to big
not likely.   If there are bugs, they are probably your doing.

Out of curiosity, what happens when you specify the LBS_SORT style initially (i.e. in the resources).  Does it sort then?

Also did you check that

GetDlgItem(hw,IDC_LIST1)

is returning the right handle?  (also, you may want to save that in a local variables so you don't have to keep calling GetDlgItem()).
LBS_SORT is not a style that can be changed at runtime.  You have to destroy the window and create a new one with the LBS_SORT flag set.
Well here's a trick I use when wanting to change the control:

1. Create a dialog with 2 listboxs (say IDC_LIST1, IDC_LIST2) at exactly same position with different style

2. Keep contents in sync (always add same contents to both lists)

3. When you want to switch modes, hide one and show the other, e.g.

// hide list 1
EnableWindow( GetDlgItem(hDlg,IDC_LIST1), FALSE ) ;
ShowWindow( GetDlgItem(hDlg,IDC_LIST1), SW_HIDE ) ;

// show list 2
EnableWindow( GetDlgItem(hDlg,IDC_LIST2), TRUE ) ;
ShowWindow( GetDlgItem(hDlg,IDC_LIST2), SW_SHOW ) ;

4. Keep track of which list is active in a boolean or integer variable.

5. In WM_INITDIALOG use tip #3 and tip #4 to set the initial control shown

Using this "work round" you can give the appearance (to the user) of changing styles radically on the fly.  This approach isn't limited to 2 list boxes (or even two identical controls) by the way
It might be easier to create one that is always sorted and use LB_ADDSTRING to add sorted items and LB_INSERTSTRNG to add them unsorted (or move them about).

But I still find it hard to believe that the sort style can't be changed.
Avatar of andla

ASKER

I suppose you are right. Thanks! But the problem is still there and this sample code worked fine so it must be the right window. To complete this question i need to know what i shall do to make an alfabetic order of all the items. One way should be to call a function that sorted the strings and then i could call LB_RESETCONTENT and LB_ADD in a loop to build up the items. The second solution should be to destroy the window and use CreateWindowEx() to build a new one but how do i keep the ID_ ?. The third solution should be to use two listboxes over eatch other so it look like one control, but the problem is that i cannot (i think) have two controls with the same ID_ so my functions works on both listboxes.

I need to know how to write the code.

Your sincerly
andla.
ASKER CERTIFIED SOLUTION
Avatar of danny_pav
danny_pav

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>> But I still find it hard to believe that the sort style can't be changed.

I saw a comment from MikeB (MFC/MS guy) a while ago that not all controls handle the WM_STYLECHANGED message.  MikeB thought this was reasonable behaviour.  In this case I would say you could argue it might be, although it would certainly be a lot more reasonable in my view if it said somewhere which controls handled it, and which didn't...
>>MikeB thought this was reasonable behaviour
MikeB believes that EVERYTHING that Microsoft does is 100% perfect.  (Don't put MS down on a question he is on, you'll never hear the end of it.  Defenitly don't use the word "bug"!)

In any case, I think the idea of using a sorted list box all the time and using the LB_ADDSTRING  and LB_INSERTSTRING was mine.
Avatar of andla

ASKER

Thanks! With a little work it now works good with LB_INSERTSTRING. I suppose changing styles on conrols created from the resource is not ment to be done that way. Perhaps it only works with CreateDialog,CreateWindow/Ex().

:-)
Your sincerely
Andla