Basic windows stuff is eluding me today. Here I have a treeview in a modeless child dialog which sends the item text to a richedit control on the parent dialog when the item is selected or checked. But the treeview retains focus, whereas I want the richedit control to keep focus, so that I can enter text into it and "drop in" item text from the treeview when it is selected. How can I do this, please?
This code will compile & run with PB Win 8.04, no fancy libraries.
This code will compile & run with PB Win 8.04, no fancy libraries.
Code:
' #COMPILE EXE #DIM ALL #INCLUDE "commctrl.inc" #INCLUDE "comdlg32.inc" #INCLUDE "RichEdit.INC" %idc_DBB_lab1 = 1317 %IDC_DBB_TREEVIEW = 1320 %IDC_main_bn = 1321 %IDC_MAIN_TB = 1323 %IDC_DBB_CLR_BN = 1324 DECLARE FUNCTION TVBrowser(BYVAL hParent AS DWORD) AS LONG DECLARE FUNCTION mainwindow ( BYVAL hParent AS DWORD ) AS LONG GLOBAL ghEditWnd AS DWORD GLOBAL gchecked, gunchecked AS DWORD '------------------------------------------------------------------------------ ' thank you Chris Boss! SUB CopyToClipboard(BYVAL Txt AS STRING) LOCAL hClip AS LONG, lpAddress AS LONG Txt = Txt + CHR$(0) hClip=GlobalAlloc(%GMEM_MOVEABLE, LEN(Txt)) lpAddress=GlobalLock(hClip) POKE$ lpAddress, Txt GlobalUnlock hClip IF OpenClipboard(%NULL) THEN EmptyClipboard SetClipboardData %CF_TEXT, hClip CloseClipboard ELSE GlobalFree hClip END IF END SUB '------------------------------------------------------------------------------ FUNCTION SampleTreeViewInsertItem(BYVAL hTree AS DWORD, BYVAL hParent AS DWORD, sItem AS STRING) AS LONG LOCAL tTVItem AS TV_ITEM LOCAL tTVInsert AS TV_INSERTSTRUCT IF hParent THEN tTVItem.mask = %TVIF_CHILDREN OR %TVIF_HANDLE tTVItem.hItem = hParent tTVItem.cchildren = 1 TreeView_SetItem hTree, tTVItem END IF tTVInsert.hParent = hParent tTVInsert.Item.Item.mask = %TVIF_TEXT tTVInsert.Item.Item.pszText = STRPTR(sItem) tTVInsert.Item.Item.cchTextMax = LEN(sItem) FUNCTION = TreeView_InsertItem(hTree, tTVInsert) END FUNCTION '------------------------------------------------------------------------------ FUNCTION SampleTreeView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount AS LONG) AS LONG LOCAL i AS LONG LOCAL j AS LONG LOCAL k AS LONG LOCAL hCtl AS DWORD LOCAL hRoot AS DWORD LOCAL hParent AS DWORD CONTROL HANDLE hDlg, lID TO hCtl FOR i = 1 TO lCount hRoot = SampleTreeViewInsertItem(hCtl, %NULL, USING$("Root#", i)) CALL SampleTreeViewInsertItem(hCtl, hRoot, "*") FOR j = 1 TO lCount hParent = SampleTreeViewInsertItem(hCtl, hRoot, USING$("Item#", j)) CALL SampleTreeViewInsertItem(hCtl, hParent, "*") FOR k = 1 TO lCount CALL SampleTreeViewInsertItem(hCtl, hParent, USING$("SubItem#_.#", j, k)) NEXT k NEXT j NEXT i END FUNCTION '------------------------------------------------------------------------------ ' tear through the treeview unchecking checkboxes SUB UnCheckAll ( hTVWnd AS DWORD, dwitem AS DWORD) LOCAL TreeItem AS TV_ITEM LOCAL i AS LONG LOCAL hitm, checked AS DWORD TreeItem.hItem = dwItem WHILE TreeItem.HItem <> %NULL TreeItem.mask = %TVIF_STATE OR %TVIF_HANDLE TreeItem.stateMask = %TVIS_STATEIMAGEMASK TReeView_getItem( hTVWnd, BYVAL VARPTR(TreeItem)) ' get item hitm = TreeView_GetChild ( hTVWnd, TreeItem.hItem) IF hitm <> %NULL THEN unCheckAll ( hTVWnd, hItm) END IF IF (TreeItem.state AND gchecked) = gchecked THEN TreeItem.state = gunchecked TreeView_setItem( hTVWnd, BYVAL VARPTR(TreeItem)) ' set state = unchecked END IF TreeItem.HItem = Treeview_GetNextSibling(hTVWnd, TreeItem.hItem) WEND END SUB '------------------------------------------------------------------------------ CALLBACK FUNCTION TVBrowser_dialogProc() STATIC hmenu, hparent, hTVWnd AS DWORD LOCAL r AS rect LOCAL s, s1 AS STRING LOCAL hDB, hedit, l, lresult AS LONG LOCAL sz AS ASCIIZ*256 LOCAL psz AS ASCIZ PTR LOCAL lpNmh AS NMHDR PTR LOCAL lpTV AS NM_TREEVIEW PTR LOCAL treeItem AS TV_ITEM LOCAL pTVITEM AS tv_item PTR LOCAL TVdi AS TV_DISPINFO LOCAL TVht AS TV_HITTESTINFO LOCAL DWPOS AS DWORD STATIC bITEMmode AS LONG ' boolean SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG hTVWnd = getdlgitem(CBHNDL, %IDC_DBB_TREEVIEW ) CONTROL ADD LABEL, CBHNDL, %idc_DBB_lab1,"check boxes press button" & s ,5, 2, 175,12 SampleTreeView(CBHNDL, %IDC_DBB_TREEVIEW, 20) ' CASE %WM_NOTIFY lpNmh = CBLPARAM SELECT CASE @lpNmh.Code CASE %NM_CLICK IF @lpNmh.idFrom = %IDC_DBB_TREEVIEW THEN ' This will ensure that when the user either clicks the checkbox or the ' buttons (+/-) the item/node will be selected. You get a strange flashing ' experience if you do not do this, comment out this code and then use a ' checkbox or the buttons and see what occurs. (found this code on MSDN) dwPos = GetMessagePos ' Get the mouse position TVht.pt.x = LO(WORD, dwPos) ' Store the mouse x pos in the hittest udt tvht.pt.y = HI(WORD, dwPos) ' Store the mouse y pos in the hittest udt MapWindowPoints(%HWND_DESKTOP, @LPnMH.hwndFrom, TVht.pt, 1) ' clicked on the checkbox? ' Get the TreeView item/node returned in the hittest udt member of hItem TreeView_HitTest( hTVWnd, BYVAL VARPTR(TVht)) ' examine the flags to see if the checkbox was hit TreeItem.mask = %TVIF_TEXT TreeItem.cchTextMax = SIZEOF(sz) TreeItem.psztext = VARPTR(sz) TreeItem.hItem = TVHT.Hitem TreeView_GetItem (hTVWnd, BYVAL VARPTR(TreeItem)) copyToClipboard ( TRIM$(sz)) SendMessage ghEditWnd, %WM_PASTE, 0, 0 ' paste text from clipboard END IF END SELECT CASE %WM_LBUTTONDOWN SendMessage CBHNDL, %WM_NCLBUTTONDOWN, %HTCAPTION, BYVAL %NULL ' force drag CASE %WM_COMMAND SELECT CASE CBCTL ' <- look at control's id CASE %IDC_DBB_CLR_BN IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN dwpos = TreeView_GetRoot( hTVWnd) Uncheckall ( hTVWnd, dwPos) END IF END SELECT END SELECT END FUNCTION '------------------------------------------------------------------------------ FUNCTION TVBrowser(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG LOCAL hDlg AS DWORD LOCAL s AS STRING DIALOG NEW hParent, "", 10, 100, 140, 220, %WS_POPUP OR %WS_CHILD OR %WS_THICKFRAME OR _ %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _ %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _ %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hdlg DIALOG SET COLOR hDlg, -1, RGB(255, 255, 155) CONTROL ADD "SysTreeView32", hDlg,%IDC_DBB_TREEVIEW, "SysTreeView32_1", 5, 15, 135, 175, %WS_CHILD OR %WS_VISIBLE OR _ %WS_TABSTOP OR %TVS_HASBUTTONS OR %TVS_HASLINES OR %TVS_CHECKBOXES OR %TVS_LINESATROOT OR %TVS_SHOWSELALWAYS, _ %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR CONTROL ADD BUTTON, hDlg, %IDC_DBB_CLR_BN, "UNCHK ALL", 0, 190, 70, 15 DIALOG SHOW MODELESS hDlg, CALL TVBrowser_dialogProc TO lRslt FUNCTION = lRslt END FUNCTION '-------------------------------------------------------------------------------- CALLBACK FUNCTION mainwindowproc() LOCAL sz AS ASCIZ * 64 LOCAL l AS LONG SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG ghEditWnd = getdlgitem(CBHNDL,%IDC_MAIN_TB) TVBrowser (0) l = sendmessage( ghEditWnd, %EM_GETEVENTMASK, 0, 0) sendmessage ghEditWnd, %EM_SETEVENTMASK, 0, l OR %ENM_CHANGE CASE %WM_LBUTTONDOWN SendMessage CBHNDL, %WM_NCLBUTTONDOWN, %HTCAPTION, BYVAL %NULL ' force drag CASE %WM_NOTIFY BEEP LOCAL nh AS NMHDR PTR nh = CBLPARAM 'More Richedit events IF CBCTL = %IDC_MAIN_TB THEN 'Get caret movement SELECT CASE @nh.code END SELECT END IF CASE %WM_COMMAND SELECT CASE CBCTL ' <- look at control's id CASE %IDC_MAIN_BN IF CBCTLMSG = %BN_CLICKED THEN DIALOG END CBHNDL, 0 CASE %IDC_MAIN_TB IF CBCTLMSG = %EN_CHANGE THEN BEEP END SELECT END SELECT END FUNCTION '-------------------------------------------------------------------------------- FUNCTION mainwindow ( BYVAL hParent AS DWORD ) AS LONG LOCAL lRslt AS LONG LOCAL hDlg AS DWORD DIALOG NEW hParent, "", 160, 100, 330, 200, %WS_POPUP OR %WS_THICKFRAME OR _ %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _ %DS_SETFONT, %WS_EX_CONTROLPARENT OR _ %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hdlg CONTROL ADD "RichEdit", hDlg, %IDC_MAIN_TB, "", 5,5,320,177, _ %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %ES_MULTILINE OR %WS_VSCROLL OR _ %WS_HSCROLL OR %ES_AUTOVSCROLL OR %ES_AUTOHSCROLL OR %ES_WANTRETURN, %WS_EX_CLIENTEDGE CONTROL ADD BUTTON, hDlg, %IDC_main_bn, "exit", 300, 185, 30, 15 DIALOG SHOW MODAL hdlg CALL mainwindowproc END FUNCTION '================================================================================= FUNCTION PBMAIN () AS LONG InitCommonControls gchecked = 2: SHIFT LEFT gchecked, 12 gunchecked = 1: SHIFT LEFT gunchecked, 12 ' '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Load the Richedit dll. '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IF LoadLibrary("RICHED32.DLL") = 0 THEN MSGBOX "Unable to load RICHED32.DLL - sorry, no point in continuing",,"File missing!" EXIT FUNCTION 'is this correct? At least it seems to terminate properly.. END IF ' ' mainwindow(0) END FUNCTION
Comment