Help needed with DBCOMBO (ON CHANGE)

Post Reply
Ollie
Posts: 233
Joined: Sat Dec 30, 2006 6:10 am

Help needed with DBCOMBO (ON CHANGE)

Post by Ollie »

I want the user the select the order of the table with a combo box

Code: Select all

LOCAL aTAGLIST:=GETORDNAMES() // {"COMPANY","SURNAME","NUMBER")
LOCAL cTAG:=ORDSETFOCUS()

...

REDEFINE DBCOMBO cTAG ID 40 items aTAGLIST list aTAGLIST of oDlg_search UPDATE ON CHANGE ORDSETFOCUS(cTAG)
... Doesn't work.

Code: Select all

REDEFINE DBCOMBO cTAG ID 40 items aTAGLIST list aTAGLIST of oDlg_search UPDATE ON CHANGE MSGINFO(cTAG)
...reveals that cTAG is not what is selected?

What am I doing wrong?
Many thanks
Ollie.

Using:
xHarbour Compiler build 1.2.1 (SimpLex) (Rev. 6406)
Borland C++ 5.5.1
FWH 9.04 (2009 Apr)
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post by James Bott »

Ollie,

This works for me. cTag shows what is selected. Can you provide a small self-contained example that shows the problem?

James

Code: Select all

#INCLUDE "FIVEWIN.CH"
#include "dbcombo.ch"

function main()

LOCAL aTAGLIST:= {"COMPANY","SURNAME","NUMBER"}
LOCAL cTAG:= "SURNAME"
local oDlg

define dialog oDlg

 @ 1,1 DBCOMBO cTAG items aTAGLIST ;
  list aTAGLIST of oDlg UPDATE ON CHANGE msgInfo(cTAG)

activate dialog oDlg

return nil
Ollie
Posts: 233
Joined: Sat Dec 30, 2006 6:10 am

Post by Ollie »

Hi James,

Your code tested fine for me too. I have found the problem only occurs when you define from a resouce.

Herewith the code and the resource too.

Thanks.

Code: Select all

#INCLUDE "FIVEWIN.CH"
#include "dbcombo.ch"

function main()

LOCAL aTAGLIST
LOCAL cTAG:="SURNAME"
LOCAL oDlg_Search, oGet_Searchkey, oBtn

DBCREATE('TEST.DBF',{                           ;
                    {"SURNAME",     "C", 30, 0}, ;
                    {"COMPANY",     "C", 30, 0}, ;
                    {"NUMBER",    "C", 7, 0}  ;
                  } )

USE TEST EXCLUSIVE NEW
      INDEX ON Upper( TEST->SURNAME ) TAG "SURNAME"
      INDEX ON Upper( TEST->COMPANY ) TAG "COMPANY"
      INDEX ON TEST->NUMBER TAG "NUMBER"

    ORDSETFOCUS( cTAG ) //Default order

    aTAGLIST:=GETORDNAMES()

   DEFINE DIALOG oDlg_Search RESOURCE "SEARCH"
   REDEFINE GET oGet_Searchkey ID 10 OF oDlg_Search PICTURE "@!K" UPDATE MESSAGE "ENTER SEARCH"
   REDEFINE LISTBOX oListBox ID 20 FIELDS //OF oDlg_Search //UPDATE ON DBLCLICK oDlg_Search:End()
   REDEFINE BUTTON oBtn ID 30 of oDlg_Search ACTION oDlg_Search:End()
   REDEFINE DBCOMBO cTAG ID 40 items aTAGLIST list aTAGLIST of oDlg_Search UPDATE ON CHANGE (MSGINFO(cTAG),ORDSETFOCUS(cTAG))
   ACTIVATE DIALOG oDlg_Search

return nil
dbcombo1.rc :

Code: Select all

// RESOURCE SCRIPT generated by "Pelles C for Windows, version 4.50".

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>

LANGUAGE LANG_ENGLISH,SUBLANG_ENGLISH_SOUTH_AFRICA

SEARCH DIALOGEX FIXED IMPURE 6, 18, 416, 236
STYLE WS_POPUP|DS_MODALFRAME|DS_CONTEXTHELP|DS_3DLOOK|WS_CAPTION|WS_SYSMENU|WS_VISIBLE
CAPTION "Search"
FONT 8, "MS Sans Serif", 0, 0, 1
BEGIN
  CONTROL "Search:", 4001, "Static", WS_GROUP, 0, 6, 28, 8
  CONTROL "Editbox", 10, "Edit", ES_AUTOHSCROLL|WS_BORDER|WS_TABSTOP, 28, 4, 162, 12
  CONTROL "", 20, "TWBrowse", WS_TABSTOP|0x00a00000, 2, 22, 414, 214
  CONTROL "Select", 30, "Button", BS_DEFPUSHBUTTON|WS_TABSTOP, 192, 4, 45, 15
  CONTROL "", 40, "ComboBox", WS_BORDER|CBS_DROPDOWN|CBS_SORT|WS_VSCROLL|WS_TABSTOP, 312, 4, 102, 68
  CONTROL "Search by:", 4003, "Static", WS_GROUP, 274, 6, 36, 8
END
Many thanks
Ollie.

Using:
xHarbour Compiler build 1.2.1 (SimpLex) (Rev. 6406)
Borland C++ 5.5.1
FWH 9.04 (2009 Apr)
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post by James Bott »

Ollie,

I had to modify the RC file considerably since I use Workshop and the Pelles C RC file was incompatible. I reduced the code to just the DBCombo control and the msgInfo still returns the selected choice. Are you still saying that you are not getting the DBCombo selection in msgInfo()? Or, is that not the problem?

I note these problems with getting the browse to display after changing the sort order. First you are not using the ALIAS clause in the LISTBOX REDEFINE. Second you are not using (cAlias)->ORDSETFOCUS() when you change the focus. Finally, you have to refresh the browse after changing the focus.

James

Code: Select all

#INCLUDE "FIVEWIN.CH"
#include "dbcombo.ch"

function main()

LOCAL aTAGLIST
LOCAL cTAG:="SURNAME"
LOCAL oDlg_Search, oGet_Searchkey, oBtn

DBCREATE('TEST.DBF',{                           ;
                    {"SURNAME",     "C", 30, 0}, ;
                    {"COMPANY",     "C", 30, 0}, ;
                    {"NUMBER",    "C", 7, 0}  ;
                  } )

USE TEST EXCLUSIVE NEW
      INDEX ON Upper( TEST->SURNAME ) TAG "SURNAME"
      INDEX ON Upper( TEST->COMPANY ) TAG "COMPANY"
      INDEX ON TEST->NUMBER TAG "NUMBER"

    ORDSETFOCUS( cTAG ) //Default order

    aTAGLIST:=GETORDNAMES()

   DEFINE DIALOG oDlg_Search RESOURCE "SEARCH"

   REDEFINE DBCOMBO cTAG ID 101 items aTAGLIST list aTAGLIST of oDlg_Search UPDATE ON CHANGE (MSGINFO(cTAG),ORDSETFOCUS(cTAG))

   ACTIVATE DIALOG oDlg_Search

return nil
Ollie
Posts: 233
Joined: Sat Dec 30, 2006 6:10 am

Post by Ollie »

Thanks for your efforts.

First let me say, when I coded the window - everything works perfectly. It must have something to do with the Resource I'm using. Let me explain what it does:

Click the ComboBox
See 3 choices - Company, Number and Surname
Click on Company
Combobox displays Surname (so does MSGINFO(cTAG)) - database is now in Surname order (although I clicked Company)
Click the ComboBox
See 3 choices - Company, Number and Surname
Click on Number
Combobox displays Company (so does MSGINFO(cTAG)) - database is now in Company order (although I clicked Number)
Click the ComboBox
See 3 choices - Company, Number and Surname
Click on Surname
Combobox displays Number (so does MSGINFO(cTAG)) - database is now in Number order (although I clicked Surname)

There is a pattern, but I can't see what's causing it. f

Here is the code and the resource file, re-done with Borland Resource

Code: Select all

function main()

LOCAL aTAGLIST
LOCAL cTAG:="SURNAME"
LOCAL oDlg_Search, oGet_Searchkey, oBtn

DBCREATE('TEST.DBF',{                           ;
                    {"SURNAME",     "C", 30, 0}, ;
                    {"COMPANY",     "C", 30, 0}, ;
                    {"NUMBER",    "C", 7, 0}  ;
                  } )

USE TEST EXCLUSIVE NEW
      INDEX ON Upper( TEST->SURNAME ) TAG "SURNAME"
      INDEX ON Upper( TEST->COMPANY ) TAG "COMPANY"
      INDEX ON TEST->NUMBER TAG "NUMBER"

    TEST->(ORDSETFOCUS( cTAG )) //Default order

    aTAGLIST:=GETORDNAMES()

   DEFINE DIALOG oDlg_Search RESOURCE "SEARCH"
   REDEFINE GET oGet_Searchkey ID 10 OF oDlg_Search PICTURE "@!K" UPDATE MESSAGE "ENTER SEARCH"
   REDEFINE BUTTON oBtn ID 20 of oDlg_Search ACTION oDlg_Search:End()
   REDEFINE DBCOMBO cTAG ID 30 of oDlg_Search items aTAGLIST list aTAGLIST UPDATE ON CHANGE (MSGINFO(cTAG),TEST->(ORDSETFOCUS(cTAG)),oListBox:REFRESH())
   REDEFINE LISTBOX oListBox VAR ID 40 OF oDlg_Search FIELDS UPDATE ON DBLCLICK oDlg_Search:End()

   ACTIVATE DIALOG oDlg_Search

return nil

Code: Select all

/****************************************************************************


dbcombo1.rc

produced by Borland Resource Workshop


*****************************************************************************/

#define DIALOG_1	1
SEARCH DIALOG 35, 52, 402, 227
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
CAPTION "Search"
FONT 8, "MS Sans Serif"
{
 COMBOBOX 30, 307, 3, 92, 71, CBS_DROPDOWNLIST | WS_TABSTOP
 LTEXT "Search for:", -1, 6, 5, 38, 8
 EDITTEXT 10, 46, 4, 141, 12, WS_BORDER | WS_TABSTOP
 LTEXT "Order:", -1, 285, 5, 22, 8
 LISTBOX 40, 2, 27, 400, 199, LBS_STANDARD
 PUSHBUTTON "Select", 20, 190, 3, 50, 14
}
Many thanks
Ollie.

Using:
xHarbour Compiler build 1.2.1 (SimpLex) (Rev. 6406)
Borland C++ 5.5.1
FWH 9.04 (2009 Apr)
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post by James Bott »

Ollie,

First, this line works fine (modified from yours):

Code: Select all

   REDEFINE DBCOMBO cTAG ID 30 of oDlg_Search ;
     items aTAGLIST list aTAGLIST UPDATE ON CHANGE msgInfo(cTag)
Next your line won't work because oListbox is a local and it is being called within the DBCombo class so it crashes.

Code: Select all

   REDEFINE DBCOMBO cTAG ID 30 of oDlg_Search items aTAGLIST list aTAGLIST ;
     UPDATE ON CHANGE (MSGINFO(cTAG),TEST->(ORDSETFOCUS(cTAG)),oListBox:REFRESH())
I don't know how you are seeing the strange results you are getting because the program crashes on me after displaying the msgInfo(). Ah, perhaps you have oListbox defined as a public?

Here is another problem. You have defined a LISTBOX in Workshop. This is a windows control called "listbox" which is not the same as the control we also call "listbox" in FW. They both are defined like this:

Redefine listbox oLbx...

But if there is a FIELDS clause, then it gets preprocessed into TWBrowse instead of TListbox (see \include\fivewin.ch). The listbox you have defined in Workshop is the Windows control, but the one you have REDEFINED in your code is a TWBrowse. It will compile this way but it will not work properly.

To use a TWBrowse in Workshop you have to define a custom control and name it TWBrowse. You have to create this custom control because it is not a standard windows control that Workshop already knows about.

There is also another way do go about what you are trying to do, and that is you can assign actions to the TWBrowse headers. Below are some notes from my notes file on how to do this. This way you don't even need to use the dbcombo.

If you don't like using the header actions, try fixing the above problems instead.

James

------------------------
Header Actions

You can attach actions to column headers using the ACTION clause. Here is an example of sorting columns:

Code: Select all

method browse()
   ...

   @0,0 listbox oLbx...

   ::setHeaders(oLbx)

   oLbx:aActions:={ {|| ::action(1,oLbx)}, {||::action(2,oLbx)} }
   ...
return self

method action(nOrder,oLbx)
   ::setOrder(nOrder)
   ::gotop()
   oLbx:gotop()
   oLbx:refresh()
   ::setHeaders(oLbx)
return nil

method setHeaders(oLbx)
   oLbx:aHeaders:={;
       if(::indexOrder()=1,"CustNo*","CustNo"), ;
       if(::indexOrder()=2,"Item*","Item"), ;
       "Price","Start","End";
       }
return nil
(To provide a visual indication of the sorted column you mark the headers with an asterisk. )
-------------------------------------------
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post by James Bott »

Ollie,

Here is your code working. It seems to even be working with your existing RC file.

James

Code: Select all

#include "fivewin.ch"
#include "dbcombo.ch"

function main()

LOCAL aTAGLIST
LOCAL cTAG:="SURNAME"
LOCAL oDlg_Search, oGet_Searchkey, oBtn

public oLISTBOX

DBCREATE('TEST.DBF',{                           ;
                    {"SURNAME",     "C", 30, 0}, ;
                    {"COMPANY",     "C", 30, 0}, ;
                    {"NUMBER",    "C", 7, 0}  ;
                  } )



USE TEST EXCLUSIVE NEW

APPEND BLANK
REPLACE SURNAME WITH "SSSSSS"
replace company with "DDDDD"
replace number with "1111111"

append blank
REPLACE SURNAME WITH "AAAAAA"
replace company with "ZZZZZZ"
replace number with "22222"


      INDEX ON Upper( TEST->SURNAME ) TAG "SURNAME"
      INDEX ON Upper( TEST->COMPANY ) TAG "COMPANY"
      INDEX ON TEST->NUMBER TAG "NUMBER"

    TEST->(ORDSETFOCUS( cTAG )) //Default order

    test->(dbgotop())

    aTAGLIST:=GETORDNAMES()

   DEFINE DIALOG oDlg_Search RESOURCE "SEARCH"
   REDEFINE GET oGet_Searchkey ID 10 OF oDlg_Search PICTURE "@!K" UPDATE MESSAGE "ENTER SEARCH"
   REDEFINE BUTTON oBtn ID 20 of oDlg_Search ACTION oDlg_Search:End()
   REDEFINE DBCOMBO cTAG ID 30 of oDlg_Search items aTAGLIST list aTAGLIST ;
      UPDATE ON CHANGE (TEST->(ORDSETFOCUS(cTAG)),test->(dbgotop()), oListBox:REFRESH())

   REDEFINE LISTBOX oListBox FIELDS ID 40 OF oDlg_Search //UPDATE ON DBLCLICK oDlg_Search:End()

   ACTIVATE DIALOG oDlg_Search

return nil
Ollie
Posts: 233
Joined: Sat Dec 30, 2006 6:10 am

Post by Ollie »

Thanks for all the help, James.

After all that, it still didn't work with my "Pelles C" resource.

It turned out "Pelles C" was sorting the items in the listbox, and those shown where different to the actual values.

Told it not to sort and everything was ok.

Thanks again for anything.
Many thanks
Ollie.

Using:
xHarbour Compiler build 1.2.1 (SimpLex) (Rev. 6406)
Borland C++ 5.5.1
FWH 9.04 (2009 Apr)
Post Reply