NTK and The NTK Project
are properties of Jn Dechereux
Home | Documentation | FAQ.

Vanilla 1.1.8 is a product of Lussumo. More Information: Documentation, Community Support.

Welcome Guest!
Want to take part in these discussions? If you have an account, sign in now.
If you don't have an account, apply for one now.
    • CommentTimeJan 31st 2010 edited
    I'm very new. NTKTBROWSE looks like just what I need. I've found "BRTEST" but the browser scroll bars don't move when resizing the window (Making the window smaller covers them up - Making my planned demo a bit embarrassing).
    Q. Can anyone help me change BRTEST.PRG to move the scroll bars ?
    Thanks Alastair
    • CommentTimeFeb 1st 2010

    I just gave a try to Brtest.exe and frankly speaking, I didn't notice such a weird behaviour.
    The datagrid SBs are automatically and correctly redrawn/updated, each time the end-user resizes the window that holds the NTKTbrowse object.

    Which 'window smaller' are U talkin about?
    Did U make some changes in brtest.prg?

    Maybe I miss something. So, it would be great if U could send us more details. The best would be a jpg snapshot of your screen. (use the [+]Attachments option)

    • CommentTimeFeb 2nd 2010
    Hi jn
    I don't think my "brtest.prg" been modified?
    Maybe it's as intended..
    However, resizing the brtest (child) window doesn't move the scroll bars with the window (brtest.jpg).
    You can see on my screen dump the child window is bigger than the data grid but the scroll bars are stuck to the edge of the data. Then when I reduce the window (brtest2.jpg) size smaller than the data grid the scroll bars become hidden, meaning I cant navigate the data grid (as would be typical).
    Maybe I've corrupted my brtest.prg source code??
    • CommentTimeFeb 2nd 2010
    wrong brtest2.jpg
    try this one
    • CommentTimeFeb 2nd 2010 edited
    Ok, I see.

    You need a self-adjustable datagrid control. Thus, when the end-user is resizing the parent window, the whole child oBrowse is automatically adjusted to the parent new dimensions.

    So, in order to implement such behaviors, we need to make some enhancements to the basic Brtest.prg.
    Though the needed changes are mainly explained below, consider the attached Brtest2.prg as containing the full modified code.

    What are those changes?

    1 – Line 397: Let's define a new fixed style for our child datagrid control.
    (It should not be a resizable window anymore).

    oB := NtkTBrowse():Init( hTBParent,;
                             0, 0, aParentRect[RECT_Width], aParentRect[RECT_Height],;
                             WS_CHILD+WS_VISIBLE+WS_VSCROLL )
    //                         WS_CHILD + WS_VISIBLE + WS_OVERLAPPED + WS_THICKFRAME + WS_VSCROLL )

    2 – Add this function at the end of your prg.
    This little function is intended to adapt the browse object dimensions, each time the end-user is resizing the parent window.

    STATIC FUNCTION AdjustBrowseToParent( oB, lUserResize )
    Local hWndP
    Default lUserResize To .F.
    If !EMPTY(oB)
       hWndP := oB:hWndParent
       oB:nubWidth := 120  // we want a 120 px width for nubs
       // Resize the whole datagrid control (nubs+data cells) according to its parent container dimensions
                      (__NTKMaxCol(hWndP) - oB:nubWidth),;
                      __NTKMaxRow(hWndP) ,;
       if !lUserResize
          NTK_PostMessage( oB:hWnd, WM_EXITSIZEMOVE, 0, 0 )
    RETURN( Nil )

    3 – Line 514 : Insert this code snippet inside the parent container 'winproc'.
    Now, we only have to tell the browse parent window, what to do and when!

       CASE message == WM_SYSCOMMAND
            IF nwParam == SC_CLOSE      // system menu double click, or Alt-F4
            ELSEIF nwParam==SC_MAXIMIZE .OR. nwParam==SC_MINIMIZE .OR. nwParam==SC_RESTORE
               // adjust the child dataGrid/Browse control to its parent container
               AdjustBrowseToParent( oB )
            **RETURN 0
            // adjust the child dataGrid/Browse control to its parent container
            AdjustBrowseToParent( oB )
       CASE message == WM_SIZE
            // adjust the child dataGrid/Browse control to its parent container
            AdjustBrowseToParent( oB )

    That's all.
    Now, download brtest2.prg+brtest2.rc into your NTKRAD subfolder, type MKRAD brtest2 at prompt, then just try it!

    Hope this few explanations will be useful. :smile:

    • CommentTimeFeb 3rd 2010
    Works a treat - thanks

    I'd also like to add some easy-edit facility to our demo.

    U-know.... right-click to reveal a copy/cut/paste (of selected) option.
    If popping up a menu is too tricky for me just now is enabling Ctrl_c, Ctrl_x, Ctrl_v easier??

    Bye for now
    • CommentTimeFeb 4th 2010 edited

    Hi Alastair,
    Glad you like it!

    >>U-know.... right-click to reveal a copy/cut/paste (of selected) option.
    >>If popping up a menu is too tricky for me just now is enabling Ctrlc, Ctrlx, Ctrl_v easier??
    Don't worry about that. Those kinds of facilities are very easy to implement with NTK.
    As the owner of a registered NTK Pro license, your package is supplied with the full NTKRad (and other derivate application tools) source code. So, feel free to have a look at the NTKDIC tool and its source code (\wntk4hrb\ntkdic). I think you'll find there your gold mine.

    Are you talking about something like that? :wink:

    • CommentTimeFeb 6th 2010

    ntkdic is a real goldmine

    thank you jnd
    • CommentTimeFeb 7th 2010 edited
    Hi jnd

    I'm busy adapting code from brtest.prg whilst learning from other demo code
    (I'm making good progress)

    I'm a bit stuck however, I would like to include a couple of "logical" fields inside my NTKTBROWSE table

    I've got a .T. or .F. displayed in the cell but, when I edit the cell, I get a tick box which won't save .T. or .F. :-(

    can you point me in the right direction for me to be able to display a nice tick then edit and save it in a ntktbrowse cell.

    thanks in advance
    • CommentTimeFeb 9th 2010 edited

    Hi Alastair,
    >>I'm busy adapting code from brtest.prg whilst learning from other demo code
    >>I'm making good progress)
    Great, I'm sure you're on the right way!

    >>can you point me in the right direction for me to be able to display a nice tick then edit and
    >>save it in a ntktbrowse cell.
    If you are wondering about a datagrid object offering checkbox abilities inside cells, like the following:

    Just keep in mind there are many different ways to do it. So, as I'm a lazy boy, I'm going to show you one of the easiest. :wink:

    Just look at the next post.

    Hope this will help you.

    • CommentTimeFeb 9th 2010 edited
    Ok - Let's go deep in NTKBrowse world!

    1 – First, you need 2 bitmaps. One showing a checked box. The other displaying an unchecked box. (e.g. Maybe you'll need those enclosed. Don't forget to remove the .jpg fake extension.)

    2 – Then, add the following lines at the end of the resource file (.rc) of your app:
    (Feel free to adapt paths to your own environment)
    // Resources for Browse objects. Must be numeric!
    1200  BITMAP  \myapp\bmp\ChkMark0.bmp     /* Blue on White Check Mark OFF */
    1201  BITMAP  \myapp\bmp\ChkMark1.bmp     /* Blue on White Check Mark ON  */

    3 – Load your PRG, move to your Browse column declarations, then let's make some extra changes to the column properties containing the logical field. Currently, your column declaration may look like this:
     oCol3 := NtkColumn():Init("MyLabel", {||data->MyLogicalField}, nil, NTK_RGB(12,15,46), NTK_RGB(200,200,255), DT_LEFT, 100 )

    Change it for that:
    oCol3 := NtkColumn():Init( "MyLabel", 0, nil, NTK_RGB(12,15,46), NTK_RGB(200,200,255), nil, 45 )
    oCol3:Bitmap := {|| IIF(  myDbf->MyLogicalField, 1201, 1200) } 
    oCol3:BitAlign := DT_CENTER

    As you can see the :bBlock (field) property is deliberately set to zero, whereas the :Bitmap property is declared as a conditional codeblock relative to the state of our logical field. So, when the Field is .T. the #1201 bitmap is displayed, otherwise the #1200 is shown.

    4 –Move to your Browse setting declarations, then check for the :doubleClick property.
    It should look like this :
    // Do edit routine
    oB:doubleClick  := { |oB,nMsg,nWparam,nLparam| DoEditCell(oB) }  

    5- Now, the last thing to do is to add this few lines to your DoEditCell() procedure:
    FUNCTION DoEditCell( oB )
    // ...
    // Var declarations, here.
    // ...
    // We don't need any GET/READ for this cell:
    // We just alternatively change MyLogicalField state 
    // from true to false (on/off) and so on.....
    IF oB:ColPos == 3     
         If .NOT. (oB:Alias)->MyLogicalField 
             REPLACE (oB:Alias)->MyLogicalField  WITH .T.
             REPLACE (oB:Alias)->MyLogicalField  WITH .F.
         oB:RefreshCurrent()                 // Repaint all fields of the current row
    // …
    // Here comes the default/standard routine regarding to
    // GET declarations, READ and REPLACE related to 
    // other cells/fields. More explanations in Brtest.prg...
    // ...

    By switching alternatively the MyLogicalField state in the current database record, the Browse column object will automatically display the #1201 or #1200 bitmap. Thus, the end-user will see a checked/unchecked box each time he double-clicks on the cell.

    That's all!
    • CommentTimeFeb 9th 2010
    Thanks once again jnd
    I overcame this functionality requirement by editing a single ASCII character which if == "Y" saves .F. and == "T"..... you know

    Your examlple using bmp with tick themn one without is perfect. I will now work to incorporate this


    p.s. is the app you posted the example of avaliable to share??
    • CommentTimeFeb 18th 2010 edited
    Hi jnd (any other NTK-ers)
    Thank you for your email. I need to complete my demo before I can take-up your paid services......
    I'm working on a dbf browse demo by evolving brtest.prg (in parallel a similar demo using visual-xHarbour).... However, being of Clipper background, I prefer "made easy" code (...NTKRAD) Therefore my NTK demo is progressing the most ;-)
    I need your help again though! I want my main window to have a toolbar. So,I have create one using DECLARE/CREATE TOOLBAR (looks good) my trouble is that my browse window completely ignores my toolbar by writing all over it, when opening or maximising....!

    I'm having trouble finding a detailed "NTK_CreateWindowEx" description. Where, I hoped I could declare the top 80 parent window pixels unusable.

    Is there a way????


    p.s should I keep calling you jnd - (this sounds unfriendly)?
    • CommentTimeFeb 20th 2010 edited

    Hmmm, strange behavior.
    Is possible to get a code snippet of your TB declarations, and also a couple of screenshots showing the problem?

    Regarding to NTK_CreateWindowEx(), you'll find the complete description running ..\doc\ntkcore.hlp
    Or browsing MSDN website at:

    But IMHO, I don't think Win32 APIs are the immediate answer to your problem. NTKRAD Toolbar commands still remain your best bet.

    • CommentTimeFeb 24th 2010 edited
    Hi guys,
    I took a few days off :wink:
    Now checking about forum news...

    Alastair, I see with great pleasure your demo project is well-advanced. :thumbup:

    Regarding your last question:
    You have to know that Toolbars are never part of the non-client area of the frame window. They are always a child of the frame (either main or child). Besides, they have to follow certain rules in order to be laid properly.
    So, if you want your Toolbar being always on top, I guess you have to do it yourself, maybe controlling Z-orders. Unlike what Ab previously said (sorry man!), you'll have to deal with Win32 Apis, via NTKCore functions and message handling...

    However, I'm agree with Ab when he says: 'NTKRAD Toolbar commands still remain your best bet'.
    I don't know much about your code, but I can easily imagine something like this:

    (A NTKrad way of doing things)
    FUNCTION MainToolBar(hWndP)
    LOCAL hWndTB
    LOCAL aWndRect := NTK_GetClientRect( hWndP )
    CREATE WINDOW hWndTB                   ;
      CLASS "ToolbarWindow32"              ; 
      AT 0,0 SIZE aWndRect[Rect_Right],055 ;
      ON PAINT ToolBarPaint()              ;
      ID IDC_MAIN_TBAR                     ;
    // -- DEFINE TOOLBAR MEMBERS (buttons)
    DECLARE TOOLBAR MEMBER INTO aTbBtnList                    ;
                    ID ID_BTN_OPEN                            ;
                    CAPTION "[O]"+CR+CR+"&Ouvrir..."          ;
                    SUPER ACCEL KEY K_o                       ;
                    ACTION Import_DB( hWndP )                 ;
                    BITMAP UP     "rOpen_up"                  ;
                    BITMAP DN     "rOpen_dn"                  ;
                    BITMAP GRAYED "rOpen_off"                 ;
                    BITMAP OVER   "rOpen_ovr"                 ;
                    SHIFT  TO 6,6                             ;
                    TOOLTIP "Ouvrir une table de la base de données"+CR+;
                            "([O] or Alt+O )"
    DECLARE TOOLBAR MEMBER INTO aTbBtnList                    ;
                    ID ID_BTN_IMPORT                          ;
                    CAPTION "[E]"+CR+CR+"&Exporter"           ;
                    SUPER ACCEL KEY K_e                       ;
                    ACTION Export_Dlg( hWndP )                ;
                    BITMAP UP     "rExport_up"                ;
                    BITMAP DN     "rExport_dn"                ;
                    BITMAP GRAYED "rExport_off"               ;
                    BITMAP OVER   "rExport_ovr"               ;
                    SHIFT  TO 6,6                             ;
                    TOOLTIP "Exporter la table courrante vers un "+CR+;
                            "fichier destination au format Excel. ( [E] or Alt+E )"
    DECLARE TOOLBAR MEMBER INTO aTbBtnList                    ;
                    ID ID_BTN_QUIT                            ;
                    CAPTION "[Q]"+CR+CR+"&Quitter"            ;
                    SUPER ACCEL KEY K_ESC                     ;  // Do not forget the close msg
                    ACTION NTK_SendCloseEvent( hWndP )        ;  // must be sent to the parent Window !!
                    BITMAP UP     "rQuit_up"                  ;
                    BITMAP DN     "rQuit_dn"                  ;
                    BITMAP GRAYED "rQuit_off"                 ;
                    BITMAP OVER   "rQuit_ovr"                 ;
                    SHIFT  TO 6,6                             ;
                    TOOLTIP "Fermer et sortir du programme"+CR+;
                            "(Alt+Q ou Esc)"
    @ 002,002 CREATE TOOLBAR FROM aTbBtnList               ;
                             INTO WINDOW hWndTB            ;
                             BUTTON HEIGHT  48             ;
                             BUTTON WIDTH   52             ;
                             BUTTON SPACING 0              ;
                             BUTTON TYPE NTK_BT_OWNERDRAWN ;
                             BUTTON STYLE BS_RIGHT         ;
                             BUTTON FONT NTK_GetStockObject(ANSI_VAR_FONT)
    FUNCTION ToolBarPaint(hWnd, message, nwParam, nlParam, hDC)
    // draw a fancy blue pipe bkg within the Main ToolBar child-window
    @ 0,0 SAY WALLPAPER ID ID_Pipe01 SIZE 46,__ntkMaxCol(hWnd) TO hWnd INTO CONTEXT hDC // Blue gradient Bar Tube

    Hope it helps.

    >>p.s should I keep calling you jnd - (this sounds unfriendly)?
    Why unfriendly? My first name is Jean-Noël. You can call me Jn, as well.