From: <mie...@us...> - 2012-09-29 03:26:40
|
Revision: 8449 http://sourceforge.net/p/oorexx/code-0/8449 Author: miesfeld Date: 2012-09-29 03:26:36 +0000 (Sat, 29 Sep 2012) Log Message: ----------- ooDialog - update release notes Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/examples/calculator.rex ooDialog/trunk/examples/controls/userStringDTP.rex ooDialog/trunk/examples/examples/publicRoutines_demo.rex ooDialog/trunk/examples/oleinfo/oleinfo.rex ooDialog/trunk/examples/oobandit.rex ooDialog/trunk/examples/oodraw.rex ooDialog/trunk/examples/oograph.rex ooDialog/trunk/examples/oophil.rex ooDialog/trunk/examples/propertySheet.tabs/PropertySheetDemo.rex ooDialog/trunk/examples/propertySheet.tabs/TabDemo.rex ooDialog/trunk/examples/propertySheet.tabs/TabOwnerDemo.rex ooDialog/trunk/examples/treeViewCustomDraw.rex Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-09-29 02:43:58 UTC (rev 8448) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-09-29 03:26:36 UTC (rev 8449) @@ -47,6 +47,25 @@ Changes in ooDialog 4.2.1 since the release of ooDialog 4.2.0 ======================================================================== +Bug Fixes in ooDialog: +---------------------- + +* #1116 Debug print outs left in ooDialog 4.2.0 + + +Feature Requests in ooDialog: +----------------------------- + +* #42 OODialog List Control Class (report) format individual lines + +* #130 OODialog List Control Class Activate sort headers + +* #483 ooDialog setColor and dialog background improvements + +* #484 ooDialog setColor methods should not be restricted to the 19 + palette indexes + + New Functionality in ooDialog: ------------------------------ @@ -129,8 +148,31 @@ In the TreeView class: find() +getItemData() +removeItemData() +setItemData() +Enhanced Methods: +----------------- + +In the DialogControl class: + +setColor() +setSysColor() + +In the DialogExtensions class: + +setControlColor() +setControlSysColor() + +In the TreeView class: + +insert() +itemInfo() +modify() + + New samples: ------------ Modified: ooDialog/trunk/examples/calculator.rex =================================================================== --- ooDialog/trunk/examples/calculator.rex 2012-09-29 02:43:58 UTC (rev 8448) +++ ooDialog/trunk/examples/calculator.rex 2012-09-29 03:26:36 UTC (rev 8449) @@ -61,15 +61,6 @@ exit /* leave program */ -/* error handling: Display the cause of the error and restart the programm */ -any: - call errorDialog "Error" rc "occurred at line" sigl":" errortext(rc) "a"x condition("o")~message - if calcDlg~isDialogActive then do - calcDlg~finished = .true - calcDlg~stopDialog - end - signal reStart - ::requires "ooDialog.cls" /* This requires loads the RxMath functions. */ @@ -290,8 +281,9 @@ |
From: <mie...@us...> - 2012-10-02 02:18:29
|
Revision: 8459 http://sourceforge.net/p/oorexx/code-0/8459 Author: miesfeld Date: 2012-10-02 02:18:26 +0000 (Tue, 02 Oct 2012) Log Message: ----------- #1117 Method handler passed wrong argument for TreeView EXPANDING event See ticket [Bugs:#1117] #486 ooDialog - the TreeView Expanding event should allow a veto See ticke [Feature-Requests:#486] Modified Paths: -------------- ooDialog/trunk/examples/treeViewCustomDraw.rex ooDialog/trunk/ooDialog/EventNotification.cls ooDialog/trunk/ooDialog/oodMessaging.cpp ooDialog/trunk/ooDialog/oodTreeView.cpp Modified: ooDialog/trunk/examples/treeViewCustomDraw.rex =================================================================== --- ooDialog/trunk/examples/treeViewCustomDraw.rex 2012-10-01 03:04:35 UTC (rev 8458) +++ ooDialog/trunk/examples/treeViewCustomDraw.rex 2012-10-02 02:18:26 UTC (rev 8459) @@ -130,7 +130,7 @@ end -- Connect dialog control events to methods in the Rexx dialog. - self~connectTreeViewEvent(IDC_TREE, "EXPANDING", "onExpanding") + self~connectTreeViewEvent(IDC_TREE, "EXPANDING", "onExpanding", .true) self~connectTreeViewEvent(IDC_TREE, "DEFAULTEDIT") self~connectTreeViewEvent(IDC_TREE, "BEGINDRAG", "DefTreeDragHandler") self~connectTreeViewEvent(IDC_TREE, "KEYDOWN", "onKeyDown") @@ -256,28 +256,35 @@ * added here. The items are loaded from a file in the same manner as the * original items are loaded from a file to build the tree. * - * When the user collapses the node, all its children items are removed. + * Note that the fourth argument to connectTreeViewEvent() was used for the + * EXPANDING event and set to true. This causes the interpreter to wait for the + * reply from this event handler, before it replies to the operating system. If + * the interpreter were to not wait for the reply, the tree-view control would + * immediately expand the item before the children were added. + * + * When the user collapses the node, all its children items are removed. This + * is done through the collapseAndReset method, which collapse the item and also + * tells the tree-view control to deallocate the children. */ ::method onExpanding unguarded expose tv - use arg tree, item, what + use arg tree, item, what, extra itemInfo. = tv~itemInfo(item) if itemInfo.!TEXT = "Special Offers" then do - if what == "COLLAPSED", tv~child(item) == 0 then do + if what == "EXPANDED", tv~child(item) == 0 then do do while lines(self~ITEM_FILE) args = self~makeArgs(item, , linein(self~ITEM_FILE)) tv~sendWith('insert', args) end - tv~expand(item) end - else if what == "EXPANDED", tv~child(item) <> 0 then do + else if what == "COLLAPSED", tv~child(item) \== 0 then do tv~collapseAndReset(item) end end -return 0 +return .true /** onKeyDown() Modified: ooDialog/trunk/ooDialog/EventNotification.cls =================================================================== --- ooDialog/trunk/ooDialog/EventNotification.cls 2012-10-01 03:04:35 UTC (rev 8458) +++ ooDialog/trunk/ooDialog/EventNotification.cls 2012-10-02 02:18:26 UTC (rev 8459) @@ -248,7 +248,7 @@ ::method connectTreeViewEvent - use strict arg id, type, msgToRise = "" + use strict arg id, type, msgToRise = "", willReply = .false if \ id~dataType("W") then id = self~resolveSymbolicId(id) if id = -1 then return -1 if msgToRise == "" then msgToRise = "on" || type @@ -271,9 +271,16 @@ when type = "KEYDOWN" then lp = -412 otherwise return -1 end - return self~addUserMsg(msgToRise, 0x0000004E, "0xFFFFFFFF", id, "0xFFFFFFFF", lp, "0xFFFFFFFF") + tag = 0 + if lp == -405 | lp == -406 then do + if willReply then tag = 0x02000006 + else tag = 0x00000006 + end + return self~addUserMsg(msgToRise, 0x0000004E, "0xFFFFFFFF", id, "0xFFFFFFFF", lp, "0xFFFFFFFF", tag) + + ::method connectTabEvent use strict arg id, type, msgToRise = "", willReply = .false if \ id~dataType("W") then id = self~resolveSymbolicId(id) Modified: ooDialog/trunk/ooDialog/oodMessaging.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodMessaging.cpp 2012-10-01 03:04:35 UTC (rev 8458) +++ ooDialog/trunk/ooDialog/oodMessaging.cpp 2012-10-02 02:18:26 UTC (rev 8459) @@ -1981,6 +1981,113 @@ return genericNotifyInvoke(c, pcpbd, methodName, idFrom, hwndFrom); } + +/** + * Handles, some of, the tree-vien event notifications. + * + * The tag code must have included the TAG_TREEVIEW flag for this function to be + * invoked. + * + * @param c + * @param methodName + * @param tag + * @param code + * @param lParam + * @param pcpbd + * + * @return MsgReplyType + * + * @remarks Note that most of the tree-view notifications are still handled + * using the old IBM ooDialog code. Currently only the + * TVN_ITEMEXPANDING and TVn_ITEMEXPANDED notifications are tagged + * with TAG_TREEVIEW. + * + * TVN_ITEMEXPANDING: The Rexx programmer returns .true expanding / + * collapsing the item is okay, or .false do not allow the expansion / + * collapse. + * + * TVN_ITEMEXPANDED: If the Rexx programmer sets 'willReply' to true, + * we wait for the reply, but discard the actual. This then has the + * 'sync' effect. + */ +MsgReplyType processTVN(RexxThreadContext *c, CSTRING methodName, uint32_t tag, uint32_t code, LPARAM lParam, pCPlainBaseDialog pcpbd) +{ + RexxObjectPtr idFrom = idFrom2rexxArg(c, lParam); + + switch ( code ) + { + case TVN_ITEMEXPANDED : + case TVN_ITEMEXPANDING : + { + NMTREEVIEW *nmtv = (NM_TREEVIEW *)lParam; + + // The arguements are the same whether we wait for the reply or not. + RexxObjectPtr handle = pointer2string(c, nmtv->itemNew.hItem); + RexxObjectPtr extra = c->String(""); + CSTRING _what = "ERROR"; + + if ( (nmtv->action & 0xf) == TVE_COLLAPSE ) + { + _what = "COLLAPSED"; + if ( nmtv->action & TVE_COLLAPSERESET ) + { + extra = c->String("RESET"); + } + } + else if ( (nmtv->action & 0xf) == TVE_EXPAND ) + { + _what = "EXPANDED"; + if ( nmtv->action & TVE_EXPANDPARTIAL ) + { + extra = c->String("PARTIAL"); + } + } + else if ( nmtv->action == TVE_TOGGLE ) + { + _what = (nmtv->itemNew.state & TVIS_EXPANDED) ? "COLLAPSED" : "EXPANDED"; + } + RexxStringObject what = c->String(_what); + + RexxArrayObject args = c->ArrayOfFour(idFrom, handle, what, extra); + + if ( (tag & TAG_EXTRAMASK) == TAG_REPLYFROMREXX ) + { + RexxObjectPtr msgReply = c->SendMessage(pcpbd->rexxSelf, methodName, args); + + if ( code == TVN_ITEMEXPANDING ) + { + msgReply = requiredBooleanReply(c, pcpbd, msgReply, methodName, false); + if ( msgReply == TheTrueObj || msgReply == TheFalseObj ) + { + // Return true to prevent the item from expanding / collapsing. + setWindowPtr(pcpbd->hDlg, DWLP_MSGRESULT, msgReply == TheTrueObj ? FALSE : TRUE); + } + } + } + else + { + invokeDispatch(c, pcpbd->rexxSelf, c->String(methodName), args); + + } + + c->ReleaseLocalReference(idFrom); + c->ReleaseLocalReference(handle); + c->ReleaseLocalReference(what); + c->ReleaseLocalReference(extra); + c->ReleaseLocalReference(args); + + return ReplyTrue; + } + + default : + break; + } + + + // This should never happen, we can't get here. + return ReplyTrue; +} + MsgReplyType processMCN(RexxThreadContext *c, CSTRING methodName, uint32_t tag, uint32_t code, LPARAM lParam, pCPlainBaseDialog pcpbd) { RexxObjectPtr rexxReply; @@ -2253,6 +2360,9 @@ // We could let the user decide through use of the .application // object. + case TAG_TREEVIEW : + return processTVN(c, m[i].rexxMethod, m[i].tag, code, lParam, pcpbd); + case TAG_TAB : return processTCN(c, m[i].rexxMethod, m[i].tag, code, lParam, pcpbd); @@ -2280,13 +2390,6 @@ np = ((LV_DISPINFO *)lParam)->item.pszText; item = ((LV_DISPINFO *)lParam)->item.iItem; } - /* do we have a tree expand/collapse? */ - else if ( (code == TVN_ITEMEXPANDED) || (code == TVN_ITEMEXPANDING) ) - { - handle = ((NM_TREEVIEW *)lParam)->itemNew.hItem; - if ( ((NM_TREEVIEW *)lParam)->itemNew.state & TVIS_EXPANDED ) np = "EXPANDED"; - else np = "COLLAPSED"; - } /* do we have a key_down? */ else if ( (code == TVN_KEYDOWN) || (code == LVN_KEYDOWN) || (code == TCN_KEYDOWN) ) { Modified: ooDialog/trunk/ooDialog/oodTreeView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodTreeView.cpp 2012-10-01 03:04:35 UTC (rev 8458) +++ ooDialog/trunk/ooDialog/oodTreeView.cpp 2012-10-02 02:18:26 UTC (rev 8459) @@ -133,6 +133,15 @@ tvi->state |= TVIS_EXPANDED; tvi->stateMask |= TVIS_EXPANDED; } + else if ( StrStrI(opts, "NOTEXPANDPARTIAL") != NULL ) + { + tvi->stateMask |= TVIS_EXPANDPARTIAL; + } + else if ( StrStrI(opts, "EXPANDPARTIAL") != NULL ) + { + tvi->state |= TVIS_EXPANDPARTIAL; + tvi->stateMask |= TVIS_EXPANDPARTIAL; + } if ( tvi->state != 0 || tvi->stateMask != 0 ) { @@ -396,7 +405,7 @@ tvi.mask = TVIF_HANDLE | TVIF_TEXT | TVIF_STATE | TVIF_IMAGE | TVIF_CHILDREN | TVIF_SELECTEDIMAGE | TVIF_PARAM; tvi.pszText = buf; tvi.cchTextMax = 255; - tvi.stateMask = TVIS_EXPANDED | TVIS_BOLD | TVIS_SELECTED | TVIS_EXPANDEDONCE | TVIS_DROPHILITED | TVIS_CUT; + tvi.stateMask = TVIS_EXPANDED | TVIS_BOLD | TVIS_SELECTED | TVIS_EXPANDEDONCE | TVIS_DROPHILITED | TVIS_CUT | TVIS_EXPANDPARTIAL; if ( TreeView_GetItem(hwnd, &tvi) == 0 ) { @@ -417,6 +426,7 @@ if ( tvi.state & TVIS_EXPANDEDONCE ) strcat(buf, "EXPANDEDONCE "); if ( tvi.state & TVIS_DROPHILITED ) strcat(buf, "INDROP "); if ( tvi.state & TVIS_CUT ) strcat(buf, "CUT "); + if ( tvi.state & TVIS_EXPANDPARTIAL) strcat(buf, "EXPANDPARTIAL "); if ( *buf != '\0' ) { *(buf + strlen(buf) - 1) = '\0'; |
From: <mie...@us...> - 2012-10-02 23:25:09
|
Revision: 8467 http://sourceforge.net/p/oorexx/code-0/8467 Author: miesfeld Date: 2012-10-02 23:25:07 +0000 (Tue, 02 Oct 2012) Log Message: ----------- ooDialog - remove debug statement, correct spelling, remove unused varible Modified Paths: -------------- ooDialog/trunk/examples/examples/useTools.rex ooDialog/trunk/ooDialog/oodData.cpp ooDialog/trunk/ooDialog/oodListView.cpp Modified: ooDialog/trunk/examples/examples/useTools.rex =================================================================== --- ooDialog/trunk/examples/examples/useTools.rex 2012-10-02 23:10:34 UTC (rev 8466) +++ ooDialog/trunk/examples/examples/useTools.rex 2012-10-02 23:25:07 UTC (rev 8467) @@ -223,7 +223,7 @@ count += 1 -- Now size the dialog to exactly fit the buttons - self~create(0, 30, count * s~width, s~height, "Tool Pallete", "NOMENU") + self~create(0, 30, count * s~width, s~height, "Tool Palette", "NOMENU") ::method defineDialog expose s buttonIDs Modified: ooDialog/trunk/ooDialog/oodData.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodData.cpp 2012-10-02 23:10:34 UTC (rev 8466) +++ ooDialog/trunk/ooDialog/oodData.cpp 2012-10-02 23:25:07 UTC (rev 8467) @@ -461,7 +461,7 @@ if ( hCtrl != NULL ) { HTREEITEM hItem = tvFindItem(hCtrl, ldat); - printf("setTreeViewData() text=%s hItem=%p\n", ldat, hItem); + if ( hItem != NULL ) { return (TreeView_SelectItem(hCtrl, hItem) ? true : false); Modified: ooDialog/trunk/ooDialog/oodListView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodListView.cpp 2012-10-02 23:10:34 UTC (rev 8466) +++ ooDialog/trunk/ooDialog/oodListView.cpp 2012-10-02 23:25:07 UTC (rev 8467) @@ -3093,8 +3093,7 @@ */ RexxMethod3(RexxObjectPtr, lv_setItemData, uint32_t, index, RexxObjectPtr, data, CSELF, pCSelf) { - LVITEM lvi = {LVIF_PARAM, index}; - RexxObjectPtr result = TheNilObj; + LVITEM lvi = {LVIF_PARAM, index}; pCDialogControl pcdc = validateDCCSelf(context, pCSelf); if ( pcdc == NULL ) |
From: <mie...@us...> - 2012-10-09 23:21:11
|
Revision: 8495 http://sourceforge.net/p/oorexx/code-0/8495 Author: miesfeld Date: 2012-10-09 23:21:08 +0000 (Tue, 09 Oct 2012) Log Message: ----------- #1126 ooDialog - args sent to the HELP event handler incorrect See ticket [Bugs:#1126] Modified Paths: -------------- ooDialog/trunk/examples/rc/treeViewCustomDraw.h ooDialog/trunk/examples/rc/treeViewCustomDraw.rc ooDialog/trunk/examples/treeViewCustomDraw.inp ooDialog/trunk/examples/treeViewCustomDraw.rex ooDialog/trunk/examples/treeViewCustomDrawI.inp ooDialog/trunk/ooDialog/TreeView.cls ooDialog/trunk/ooDialog/ooDialog.hpp ooDialog/trunk/ooDialog/oodListView.cpp ooDialog/trunk/ooDialog/oodMessaging.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp ooDialog/trunk/ooDialog/oodTreeView.cpp Modified: ooDialog/trunk/examples/rc/treeViewCustomDraw.h =================================================================== --- ooDialog/trunk/examples/rc/treeViewCustomDraw.h 2012-10-09 02:16:59 UTC (rev 8494) +++ ooDialog/trunk/examples/rc/treeViewCustomDraw.h 2012-10-09 23:21:08 UTC (rev 8495) @@ -47,6 +47,7 @@ #define IDC_PB_INFO 114 #define IDC_TREE 120 #define IDC_CHK_FOLDER 1001 +#define IDC_PB_SORT 1002 #define IDC_RB_SIBLING 1004 #define IDC_RB_CHILD 1006 #define IDC_EDIT_NAME 1007 Modified: ooDialog/trunk/examples/rc/treeViewCustomDraw.rc =================================================================== --- ooDialog/trunk/examples/rc/treeViewCustomDraw.rc 2012-10-09 02:16:59 UTC (rev 8494) +++ ooDialog/trunk/examples/rc/treeViewCustomDraw.rc 2012-10-09 23:21:08 UTC (rev 8495) @@ -69,6 +69,7 @@ PUSHBUTTON "New Item", IDC_PB_NEW, 10, 250, 62, 14, WS_GROUP PUSHBUTTON "Delete Item", IDC_PB_DELETE, 10, 268, 62, 14 PUSHBUTTON "Item Information", IDC_PB_INFO, 10, 287, 62, 14 + PUSHBUTTON "Reverse Sort", IDC_PB_SORT, 89, 250, 62, 14, WS_GROUP PUSHBUTTON "Expand All", IDC_PB_EXP_ALL, 89, 268, 62, 14 PUSHBUTTON "Collapse All", IDC_PB_COL_ALL, 89, 287, 62, 14 PUSHBUTTON "Help", IDHELP, 202, 268, 62, 14 Modified: ooDialog/trunk/examples/treeViewCustomDraw.inp =================================================================== --- ooDialog/trunk/examples/treeViewCustomDraw.inp 2012-10-09 02:16:59 UTC (rev 8494) +++ ooDialog/trunk/examples/treeViewCustomDraw.inp 2012-10-09 23:21:08 UTC (rev 8495) @@ -1,105 +1,105 @@ -"Products",0,1,"EXPANDED" -,"Computers",0,1 -,,"Motherboards",0,1 -,,,"SCSI Motherboards",0,1 -,,,,"Motherboard A",2,3 -,,,,"Motherboard B",2,3 -,,,,"...",2,3 -,,,"IDE Motherboards",0,1 -,,,,"Motherboard A",2,3 -,,,,"Motherboard B",2,3 -,,,,"...",2,3 -,,"PC Drives",0,1 -,,,"IDE Drives",0,1 -,,,,"Drive A",2,3 -,,,,"Drive B",2,3 -,,,,"...",2,3 -,,,"SCSI Drives",0,1 -,,,,"Drive A",2,3 -,,,,"Drive B",2,3 -,,,,"...",2,3 -,,,"CD ROM Drives",0,1 -,,,,"Internal CD ROM Drives",0,1 -,,,,,"Drive A",2,3 -,,,,,"Drive B",2,3 -,,,,,"...",2,3 -,,,,"External CD ROM Drives",0,1 -,,,,,"Drive A",2,3 -,,,,,"Drive B",2,3 -,,,,,"...",2,3 -,,,,,"Housings for External CD ROM Drives",0,1 -,,,,,,"Housing A",2,3 -,,,,,,"Housings B",2,3 -,,,,,,"...",2,3 -,,,"CD Recorders",0,1 -,,,,"CD Recorder A",2,3 -,,,,"CD Recorder B",2,3 -,,,,"...",2,3 -,,"Graphic Cards & Monitors",0,1 -,,,"Graphic Cards",0,1 -,,,"Monitors",0,1 -,,,,"17 inch Monitors",0,1 -,,,,,"Monitor A",2,3 -,,,,,"Monitor B",2,3 -,,,,,"...",2,3 -,,,,"19 inch Monitors",0,1 -,,,,,"Monitor A",2,3 -,,,,,"Monitor B",2,3 -,,,,,"...",2,3 -,,"Modems & Fax",0,1 -,,"Software",0,1 -,,,"Office Software",0,1 -,,,"Graphic Software",0,1 -,,,"Games",0,1 -,,"Printers",0,1 -,,,"Ink Jet Printers",0,1 -,,,"Laser Printers",0,1 -,"Audio Video and Home Entertainment",0,1 -,,"Hi-Fi Components",0,1 -,,"Loudspeakers",0,1 -,,"Microphones",0,1 -,,"Video and Accessories",0,1 -,"Home Electronics",0,1 -,,"Alarm Systems",0,1 -,,,"Alarm Sensors",0,1 -,,,"Security Lights",0,1 -,,"Weather Monitoring",0,1 -,,"Analogue and Digital Clocks",0,1 -,,"Ventilation Equipment",0,1 -,,"Halogen Lighting",0,1 -,"Communications",0,1 -,"Car Audio and Car Products",0,1 -,"Books",0,1 -,,"Software",0,1 -,,,"Book A",2,3 -,,,"Book B",2,3 -,,,"...",2,3 -,,"Hardware",0,1 -,,,"Book A",2,3 -,,,"Book B",2,3 -,,,"...",2,3 -,,"Introduction to Electronic",0,1 -,,,"Book A",2,3 -,,,"Book B",2,3 -,,,"...",2,3 -,,"Solar and Alternative Energy",0,1 -,,,"Book A",2,3 -,,,"Book B",2,3 -,,,"...",2,3 -,,"Batteries/Chargers and Power Supplies",0,1 -,,,"Book A",2,3 -,,,"Book B",2,3 -,,,"...",2,3 -,,"Car Mechanics",0,1 -,,,"Book A",2,3 -,,,"Book B",2,3 -,,,"...",2,3 -,,"Audio / Video & Home Entertainment",0,1 -,,,"Book A",2,3 -,,,"Book B",2,3 -,,,"...",2,3 -,,"Satellite Technology",0,1 -,,,"Book A",2,3 -,,,"Book B",2,3 -,,,"...",2,3 -,"Special Offers",0,1, ,"1" +"Products",0,1,"EXPANDED", ,"Products" +,"Computers",0,1,,,"Computers" +,,"Motherboards",0,1,,,"Motherboards" +,,,"SCSI Motherboards",0,1,,,"SCSI Motherboards" +,,,,"Motherboard A",2,3,,,"Motherboard A" +,,,,"Motherboard B",2,3,,,"Motherboard B" +,,,,"...",2,3,,,"..." +,,,"IDE Motherboards",0,1,,,"IDE Motherboards" +,,,,"Motherboard A",2,3,,,"Motherboard A" +,,,,"Motherboard B",2,3,,,"Motherboard B" +,,,,"...",2,3,,,"..." +,,"PC Drives",0,1,,,"PC Drives" +,,,"IDE Drives",0,1,,,"IDE Drives" +,,,,"Drive A",2,3,,,"Drive A" +,,,,"Drive B",2,3,,,"Drive B" +,,,,"...",2,3,,,"..." +,,,"SCSI Drives",0,1,,,"SCSI Drives" +,,,,"Drive A",2,3,,,"Drive A" +,,,,"Drive B",2,3,,,"Drive B" +,,,,"...",2,3,,,"..." +,,,"CD ROM Drives",0,1,,,"CD ROM Drives" +,,,,"Internal CD ROM Drives",0,1,,,"Internal CD ROM Drives" +,,,,,"Drive A",2,3,,,"Drive A" +,,,,,"Drive B",2,3,,,"Drive B" +,,,,,"...",2,3,,,"..." +,,,,"External CD ROM Drives",0,1,,,"External CD ROM Drives" +,,,,,"Drive A",2,3,,,"Drive A" +,,,,,"Drive B",2,3,,,"Drive B" +,,,,,"...",2,3,,,"..." +,,,,,"Housings for External CD ROM Drives",0,1,,,"Housings for External CD ROM Drives" +,,,,,,"Housing A",2,3,,,"Housing A" +,,,,,,"Housing B",2,3,,,"Housing B" +,,,,,,"...",2,3,,,"..." +,,,"CD Recorders",0,1,,,"CD Recorders" +,,,,"CD Recorder A",2,3,,,"CD Recorder A" +,,,,"CD Recorder B",2,3,,,"CD Recorder B" +,,,,"...",2,3,,,"..." +,,"Graphic Cards & Monitors",0,1,,,"Graphic Cards & Monitors" +,,,"Graphic Cards",0,1,,,"Graphic Cards" +,,,"Monitors",0,1,,,"Monitors" +,,,,"17 inch Monitors",0,1,,,"17 inch Monitors" +,,,,,"Monitor A",2,3,,,"Monitor A" +,,,,,"Monitor B",2,3,,,"Monitor B" +,,,,,"...",2,3,,,"..." +,,,,"19 inch Monitors",0,1,,, +,,,,,"Monitor A",2,3,,,"Monitor A" +,,,,,"Monitor B",2,3,,,"Monitor B" +,,,,,"...",2,3,,,"..." +,,"Modems & Fax",0,1,,,"Modems & Fax" +,,"Software",0,1,,,"Software" +,,,"Office Software",0,1,,,"Office Software" +,,,"Graphic Software",0,1,,,"Graphic Software" +,,,"Games",0,1,,,"Games" +,,"Printers",0,1,,,"Printers" +,,,"Ink Jet Printers",0,1,,,"Ink Jet Printers" +,,,"Laser Printers",0,1,,,"Laser Printers" +,"Audio Video and Home Entertainment",0,1,,,"Audio Video and Home Entertainment" +,,"Hi-Fi Components",0,1,,,"Hi-Fi Components" +,,"Loudspeakers",0,1,,,"Loudspeakers" +,,"Microphones",0,1,,,"Microphones" +,,"Video and Accessories",0,1,,,"Video and Accessories" +,"Home Electronics",0,1,,,"Home Electronics" +,,"Alarm Systems",0,1,,,"Alarm Systems" +,,,"Alarm Sensors",0,1,,,"Alarm Sensors" +,,,"Security Lights",0,1,,,"Security Lights" +,,"Weather Monitoring",0,1,,,"Weather Monitoring" +,,"Analogue and Digital Clocks",0,1,,,"Analogue and Digital Clocks" +,,"Ventilation Equipment",0,1,,,"Ventilation Equipment" +,,"Halogen Lighting",0,1,,,"Halogen Lighting" +,"Communications",0,1,,,"Communications" +,"Car Audio and Car Products",0,1,,,"Car Audio and Car Products" +,"Books",0,1,,,"...""Books" +,,"Software",0,1,,,"Software" +,,,"Book A",2,3,,,"Book A" +,,,"Book B",2,3,,,"Book B" +,,,"...",2,3,,,"..." +,,"Hardware",0,1,,,"Hardware" +,,,"Book A",2,3,,,"Book A" +,,,"Book B",2,3,,,"Book B" +,,,"...",2,3,,,"..." +,,"Introduction to Electronic",0,1,,,"Introduction to Electronic" +,,,"Book A",2,3,,,"Book A" +,,,"Book B",2,3,,,"Book B" +,,,"...",2,3,,,"..." +,,"Solar and Alternative Energy",0,1,,,"Solar and Alternative Energy" +,,,"Book A",2,3,,,"Book A" +,,,"Book B",2,3,,,"Book B" +,,,"...",2,3,,,"..." +,,"Batteries/Chargers and Power Supplies",0,1,,,"Batteries/Chargers and Power Supplies" +,,,"Book A",2,3,,,"Book A" +,,,"Book B",2,3,,,"Book B" +,,,"...",2,3,,,"..." +,,"Car Mechanics",0,1,,,"Car Mechanics" +,,,"Book A",2,3,,,"Book A" +,,,"Book B",2,3,,,"Book B" +,,,"...",2,3,,,"..." +,,"Audio / Video & Home Entertainment",0,1,,,"Audio / Video & Home Entertainment" +,,,"Book A",2,3,,,"Book A" +,,,"Book B",2,3,,,"Book B" +,,,"...",2,3,,,"..." +,,"Satellite Technology",0,1,,,"Satellite Technology" +,,,"Book A",2,3,,,"Book A" +,,,"Book B",2,3,,,"Book B" +,,,"...",2,3,,,"..." +,"Special Offers",0,1, ,"1","Special Offers" Modified: ooDialog/trunk/examples/treeViewCustomDraw.rex =================================================================== --- ooDialog/trunk/examples/treeViewCustomDraw.rex 2012-10-09 02:16:59 UTC (rev 8494) +++ ooDialog/trunk/examples/treeViewCustomDraw.rex 2012-10-09 23:21:08 UTC (rev 8495) @@ -42,7 +42,8 @@ * This example demonstrates many of the features of a tree-view control. * Including, but not limited to: drag and drop of items, label editing of * items, custom draw, using image lists to supply the icons for tree-view - * items, etc.. + * items, using a custom compare function in the Rexx dialog to sort the + * tree-view items, etc.. */ -- Use the global .constDir for symbolic IDs and turn automatic data @@ -137,6 +138,7 @@ self~connectButtonEvent(IDC_PB_NEW, "CLICKED", "onNewItem") self~connectButtonEvent(IDC_PB_DELETE, "CLICKED", "onDeleteItem") + self~connectButtonEvent(IDC_PB_SORT, "CLICKED", "onSortChildren") self~connectButtonEvent(IDC_PB_EXP_ALL, "CLICKED", "onExpandAll") self~connectButtonEvent(IDC_PB_COL_ALL, "CLICKED", "onCollapseAll") self~connectButtonEvent(IDC_PB_INFO, "CLICKED", "onItemInfo") @@ -276,7 +278,7 @@ if what == "EXPANDED", tv~child(item) == 0 then do do while lines(self~ITEM_FILE) args = self~makeArgs(item, , linein(self~ITEM_FILE)) - tv~sendWith('insert', args) + newItem = tv~sendWith('insert', args) end end else if what == "COLLAPSED", tv~child(item) \== 0 then do @@ -353,6 +355,59 @@ return 0 +/** onSortChildre() + * + * This is the event handler for the 'Reverse Sort' push button. This method is + * invoked when the user pushes that button. + * + * Note that the tree-view provides a function to sort the children of an item, + * but it only sorts in ascending alphabetical order of the item text. The + * ooDialog TreeView class provides that function in the sortChildren() method. + * + * To sort in any other order requires using the sortChildrenCB() method. With + * this method, the programmer names a 'call back' method in the Rexx dialog. + * This method is then invoked by the tree-view for each item it needs to + * determine the order of. + * + * This is what we do here, we use the sortChildrenCB method and provide on own + * comparsion method, rexxSort(). + * + * We sort the children of the selected item. If no item is selected we sort + * the children of the root item. Note that only the direct children of the + * parent item are sorted. To sort all items, the programmer would need to + * implement a recursive function, similar to the expandAll() or collapseAll() + * functions. + */ +::method onSortChildren unguarded + expose tv + + selectedItem = tv~selected + if selectedItem == 0 then selectedItem = tv~root + + ret = tv~sortChildrenCB(selectedItem, rexxSort) + + +/** rexxSort() + * + * This is our comparison callback function. We are passed the user item data + * for the first tree-view item and the user item data for the second tree-view + * item. The method needs to return 1 if the first item is greater than the + * second, -1 if the first item is less than the second, and 0 if the two items + * are equivalent. + * + * In this program, for every tree-view item inserted, we set the item data for + * that item to be the text of the item. Then, in our comparison function here, + * we just do a reverse comparison of that text. This orders the items in + * descending order rather than ascending order. The userParam argument is + * ignored here. + */ +::method rexxSort unguarded + use arg itemData1, itemData2, userParam + + -- Reverse sort: + return itemData2~compareTo(itemData1) + + /** onExpandAll() * * This is the event handler for the 'Expand All' push button. This method is @@ -481,6 +536,7 @@ /*- - - - - - - - - - Helper Methods - - - - - - - - - - - - - - - - - - - - -*/ + /** expandAll() * * This helper method recursively expands all children nodes of the specified @@ -742,15 +798,16 @@ addAsFolder = folderChk~checked -- Now insert the item either as a child or a sibling depending on what the - -- user requested. + -- user requested. Note that we set the item data on each insert to the text + -- of the inserted item. if childRB~checked then do - if addAsFolder then newItem = treeControl~insert(selected, , text, self~UNSELECTED_FOLDER, self~SELECTED_FOLDER) - else newItem = treeControl~insert(selected, , text, self~UNSELECTED_LEAF, self~SELECTED_LEAF) + if addAsFolder then newItem = treeControl~insert(selected, , text, self~UNSELECTED_FOLDER, self~SELECTED_FOLDER, , , text) + else newItem = treeControl~insert(selected, , text, self~UNSELECTED_LEAF, self~SELECTED_LEAF, , , text) treeControl~expand(treeControl~parent(newItem)) end else do - if addAsFolder then treeControl~insert(treeControl~Parent(selected), , text, self~UNSELECTED_FOLDER, self~SELECTED_FOLDER) - else treeControl~insert(treeControl~Parent(selected), , text, self~UNSELECTED_LEAF, self~SELECTED_LEAF) + if addAsFolder then treeControl~insert(treeControl~Parent(selected), , text, self~UNSELECTED_FOLDER, self~SELECTED_FOLDER, , , text) + else treeControl~insert(treeControl~Parent(selected), , text, self~UNSELECTED_LEAF, self~SELECTED_LEAF, , , text) end -- Finally, quit by invoking the super class ok() method. Modified: ooDialog/trunk/examples/treeViewCustomDrawI.inp =================================================================== --- ooDialog/trunk/examples/treeViewCustomDrawI.inp 2012-10-09 02:16:59 UTC (rev 8494) +++ ooDialog/trunk/examples/treeViewCustomDrawI.inp 2012-10-09 23:21:08 UTC (rev 8495) @@ -1,10 +1,10 @@ -"Currency Converter with Pocket Calculator Function",2,3 -"Cordless Bicycle Computer with 9 functions",2,3 -"Digital Watch",2,3 -"Accu Charger",2,3 -"Inkjet Printer",2,3 -"Diskettes",2,3 -"Car Radio",2,3 -"The Software Catalog",2,3 -"VHS Video Camera",2,3 -"External CD ROM |
From: <mie...@us...> - 2012-10-11 02:58:12
|
Revision: 8499 http://sourceforge.net/p/oorexx/code-0/8499 Author: miesfeld Date: 2012-10-11 02:58:09 +0000 (Thu, 11 Oct 2012) Log Message: ----------- #489 ooDialog - TreeView class should support info tips See ticket [Feature-requests:#489] #490 ooDialog - ListView class should support info tips See ticket [Feature-requests:#490] Modified Paths: -------------- ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.h ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.rc ooDialog/trunk/examples/rc/treeViewCustomDraw.rc ooDialog/trunk/examples/treeViewCustomDraw.inp ooDialog/trunk/examples/treeViewCustomDraw.rex ooDialog/trunk/ooDialog/DynamicDialog.cls ooDialog/trunk/ooDialog/EventNotification.cls ooDialog/trunk/ooDialog/oodMessaging.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp ooDialog/trunk/ooDialog/oodUser.cpp Modified: ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex =================================================================== --- ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex 2012-10-11 02:58:09 UTC (rev 8499) @@ -45,7 +45,8 @@ * * Demonstrates the different views possible in the list-view control. Shows * how to use the ControlDialog class to populate each page in a tab - * control. + * control. Demonstrates some other list-view features, such as info tips, + * etc.. * */ @@ -89,12 +90,18 @@ self~connectButtonEvent(IDC_PB_FORWARD, "CLICKED", "onForward") self~connectButtonEvent(IDC_PB_BACKWARD, "CLICKED", "onBackward") + self~connectButtonEvent(IDC_CK_INFOTIPS, "CLICKED", onCheckClicked) + self~connectTabEvent(IDC_TAB, 'SELCHANGE', 'onNewTab') ::method initDialog - expose tabControl pageDialog smallIcons normalIcons records pbBackward pbForward + expose tabControl pageDialog smallIcons normalIcons records pbBackward pbForward ckInfoTips + -- Set the Use Info Tips check box. + ckInfoTips = self~newCheckBox(IDC_CK_INFOTIPS) + ckInfoTips~check + -- Save a reference to the push buttons. pbBackward = self~newPushButton(IDC_PB_BACKWARD) pbForward = self~newPushButton(IDC_PB_Forward) @@ -116,6 +123,7 @@ tabControl~setMinTabWidth(w) pageDialog = .PageDialog~new("rc\oodListViews.rc", IDD_PAGE, , , , , self) + pageDialog~useInfoTips = .true pageDialog~initialize(smallIcons, normalIcons, records) -- Use execute() to properly start a ControlDialog. @@ -198,6 +206,18 @@ dlg~setWindowPos(tabControl~hwnd, displayRect, "SHOWWINDOW NOOWNERZORDER") +/** onCheckClicked() + * + * This is the event handler for the CLICKED event of the Use Info Tips check + * box. Each time it is clicked, we update the Page dialog with its state. + */ +::method onCheckClicked unguarded + expose ckInfoTips pageDialog + + if ckInfoTips~checked then pageDialog~useInfoTips = .true + else pageDialog~useInfoTips = .false + + /** onNewTab() * * This is the method we connected to the SELCHANGE event of the tab control. @@ -308,6 +328,13 @@ return self~ok:super +/** initAutoDetection() + * + * We turn off auto detection for this dialog. + */ +::method initAutoDetection + self~noAutoDetection + /** checkButtons() * * Enables or disables the forwards / backwards buttons to fit the current @@ -424,6 +451,11 @@ \* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ ::class 'PageDialog' subclass RcControlDialog +-- This attribute allows the parent dialog to notify us if the Use Info Tips +-- check box is checked or not. When it is not checked, we don't display any +-- info tips. +::attribute useInfoTips + ::method initialize expose smallIcons normalIcons records use strict arg smallIcons, normalIcons, records @@ -432,11 +464,12 @@ self~connectListViewEvent(IDC_LISTVIEW, "ACTIVATE", "onDoubleClick") self~connectListViewEvent(IDC_LISTVIEW, "BEGINDRAG", "DefListDragHandler") self~connectListViewEvent(IDC_LISTVIEW, "DEFAULTEDIT") + self~connectListViewEvent(IDC_LISTVIEW, "GETINFOTIP") self~initUpdateListView(IDC_LISTVIEW) ::method initDialog - expose lv smallIcons normalIcons records + expose lv smallIcons normalIcons records ckInfoTips useInfoTips lv = self~newListView(IDC_LISTVIEW) @@ -454,7 +487,7 @@ self~addRecord(r, .false) end - lv~addExtendedStyle("FULLROWSELECT DOUBLEBUFFER GRIDLINES") + lv~addExtendedStyle("FULLROWSELECT DOUBLEBUFFER GRIDLINES INFOTIP") /** refreshView() @@ -576,6 +609,35 @@ lv~focus(0) +/** onGetInfoTip() + * + * This is the event handler for the INFOTIP event. This method is invoked when + * the list-view wants the text for an info tip. + * + * If this method returns the empty string then no info tip will be shown. + * Otherwise, the info tip will contain the text sent back. + * + * The maxLen argument will be the maximum length allowed for the returned text. + * You should never assume what this lenght is, although it appears to usually + * be 1023. If the text sent back is longer than maxLen, it will automatically + * be truncated. + */ +::method onGetInfoTip unguarded + expose lv records useInfoTips + use arg id, item, text, maxLen + + text = '' + + if useInfoTips then do + r = records[item + 1] + text = r~firstName r~lastName '('r~age')' || .endOfLine || - + r~street || .endOfLine || - + r~city',' r~state r~zipcode + end + + return text + + /** addRecord() * * Used to add an item to the list view. @@ -592,7 +654,8 @@ iconSex = 0 if rec~sex = "F" then iconSex = 1 - lv~addRow(, iconSex, rec~lastName', 'rec~firstName, rec~street, rec~city, rec~state, rec~ZipCode, rec~age) + index = lv~addRow(, iconSex, rec~lastName', 'rec~firstName, rec~street, rec~city, rec~state, rec~ZipCode, rec~age) + lv~setItemData(index, rec~firstName rec~lastName) if newRecord then records~append(rec) Modified: ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.h =================================================================== --- ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.h 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.h 2012-10-11 02:58:09 UTC (rev 8499) @@ -56,3 +56,4 @@ #define IDC_EDIT_AGE 307 #define IDC_EDIT_STATE 308 #define IDC_EDIT_ZIPCODE 309 +#define IDC_CK_INFOTIPS 1002 Modified: ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.rc =================================================================== --- ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.rc 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.rc 2012-10-11 02:58:09 UTC (rev 8499) @@ -69,17 +69,18 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDD_LISTVIEWS DIALOG 0, 0, 400, 219 +IDD_LISTVIEWS DIALOG 0, 0, 400, 242 STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU CAPTION "List Views" FONT 8, "Ms Shell Dlg" { CONTROL "", IDC_TAB, WC_TABCONTROL, WS_TABSTOP, 10, 10, 380, 175 - PUSHBUTTON "Backward", IDC_PB_BACKWARD, 10, 195, 62, 14 - PUSHBUTTON "Forward", IDC_PB_FORWARD, 77, 195, 62, 14 - PUSHBUTTON "Add Record", IDC_PB_ADDRECORD, 167, 195, 62, 14 - DEFPUSHBUTTON "OK", IDOK, 261, 195, 62, 14 - PUSHBUTTON "Cancel", IDCANCEL, 328, 195, 62, 14 + AUTOCHECKBOX "Use Info Tips", IDC_CK_INFOTIPS, 10, 194, 81, 13 + PUSHBUTTON "Backward", IDC_PB_BACKWARD, 10, 218, 62, 14 + PUSHBUTTON "Forward", IDC_PB_FORWARD, 77, 218, 62, 14 + PUSHBUTTON "Add Record", IDC_PB_ADDRECORD, 167, 218, 62, 14 + DEFPUSHBUTTON "OK", IDOK, 261, 218, 62, 14 + PUSHBUTTON "Cancel", IDCANCEL, 328, 218, 62, 14 } Modified: ooDialog/trunk/examples/rc/treeViewCustomDraw.rc =================================================================== --- ooDialog/trunk/examples/rc/treeViewCustomDraw.rc 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/examples/rc/treeViewCustomDraw.rc 2012-10-11 02:58:09 UTC (rev 8499) @@ -65,7 +65,7 @@ CAPTION "Crazy Sam's Emporium - Inventory" FONT 8, "MS Sans Serif" { - CONTROL "Tree", IDC_TREE, WC_TREEVIEW, WS_BORDER | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS, 10, 10, 254, 231 + CONTROL "Tree", IDC_TREE, WC_TREEVIEW, WS_BORDER | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | TVS_INFOTIP, 10, 10, 254, 231 PUSHBUTTON "New Item", IDC_PB_NEW, 10, 250, 62, 14, WS_GROUP PUSHBUTTON "Delete Item", IDC_PB_DELETE, 10, 268, 62, 14 PUSHBUTTON "Item Information", IDC_PB_INFO, 10, 287, 62, 14 Modified: ooDialog/trunk/examples/treeViewCustomDraw.inp =================================================================== --- ooDialog/trunk/examples/treeViewCustomDraw.inp 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/examples/treeViewCustomDraw.inp 2012-10-11 02:58:09 UTC (rev 8499) @@ -69,7 +69,7 @@ ,,"Halogen Lighting",0,1,,,"Halogen Lighting" ,"Communications",0,1,,,"Communications" ,"Car Audio and Car Products",0,1,,,"Car Audio and Car Products" -,"Books",0,1,,,"...""Books" +,"Books",0,1,,,"Books" ,,"Software",0,1,,,"Software" ,,,"Book A",2,3,,,"Book A" ,,,"Book B",2,3,,,"Book B" Modified: ooDialog/trunk/examples/treeViewCustomDraw.rex =================================================================== --- ooDialog/trunk/examples/treeViewCustomDraw.rex 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/examples/treeViewCustomDraw.rex 2012-10-11 02:58:09 UTC (rev 8499) @@ -43,7 +43,7 @@ * Including, but not limited to: drag and drop of items, label editing of * items, custom draw, using image lists to supply the icons for tree-view * items, using a custom compare function in the Rexx dialog to sort the - * tree-view items, etc.. + * tree-view items, displaying info tips, etc.. */ -- Use the global .constDir for symbolic IDs and turn automatic data @@ -135,6 +135,7 @@ self~connectTreeViewEvent(IDC_TREE, "DEFAULTEDIT") self~connectTreeViewEvent(IDC_TREE, "BEGINDRAG", "DefTreeDragHandler") self~connectTreeViewEvent(IDC_TREE, "KEYDOWN", "onKeyDown") + self~connectTreeViewEvent(IDC_TREE, "GETINFOTIP", "onGetInfoTip") self~connectButtonEvent(IDC_PB_NEW, "CLICKED", "onNewItem") self~connectButtonEvent(IDC_PB_DELETE, "CLICKED", "onDeleteItem") @@ -355,6 +356,24 @@ return 0 +/** onGetInfoTip() + * + * This is the event handler for the INFOTIP event. It is invoked when the + * tree-view wants the text to display in the info tip. + * + * If we return the empty string, then no info tip is displayed. Otherwise, the + * text returned is displayed. Here, we only return text when the userData is + * the string: '...' In that case we return some text. In all other cases we + * return the empty string and no info tip is displayed. + */ +::method onGetInfoTip unguarded + expose tv + use arg id, hItem, text, maxLen, userData + + if userData == '...' then return 'There are too many books to list' + else return '' + + /** onSortChildre() * * This is the event handler for the 'Reverse Sort' push button. This method is Modified: ooDialog/trunk/ooDialog/DynamicDialog.cls =================================================================== --- ooDialog/trunk/ooDialog/DynamicDialog.cls 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/ooDialog/DynamicDialog.cls 2012-10-11 02:58:09 UTC (rev 8499) @@ -920,6 +920,7 @@ if style~wordpos("TVS_EDITLABELS") > 0 then ret = ret || " EDIT" if style~wordpos("TVS_HASBUTTONS") > 0 then ret = ret || " BUTTONS" if style~wordpos("TVS_HASLINES") > 0 then ret = ret || " LINES" + if style~wordpos("TVS_INFOTIP") > 0 then ret = ret || " INFOTIP" if style~wordpos("TVS_LINESATROOT") > 0 then ret = ret || " ATROOT" if style~wordpos("TVS_SHOWSELALWAYS") > 0 then ret = ret || " SHOWSELALWAYS" if style~wordpos("WS_BORDER") = 0 then ret = ret || " NOBORDER" Modified: ooDialog/trunk/ooDialog/EventNotification.cls =================================================================== --- ooDialog/trunk/ooDialog/EventNotification.cls 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/ooDialog/EventNotification.cls 2012-10-11 02:58:09 UTC (rev 8499) @@ -247,40 +247,6 @@ ::method connectAllSBEvents external "LIBRARY oodialog en_connectAllSBEvents" -::method connectTreeViewEvent - use strict arg id, type, msgToRise = "", willReply = .false - if \ id~dataType("W") then id = self~resolveSymbolicId(id) - if id = -1 then return -1 - if msgToRise == "" then msgToRise = "on" || type - type = type~translate - select - when type = "SELCHANGING" then lp = -401 - when type = "SELCHANGED" then lp = -402 - when type = "EXPANDING" then lp = -405 - when type = "EXPANDED" then lp = -406 - when type = "BEGINDRAG" then lp = -407 - when type = "BEGINRDRAG" then lp = -408 - when type = "DELETE" then lp = -409 - when type = "BEGINEDIT" then lp = -410 - when type = "ENDEDIT" then lp = -411 - when type = "DEFAULTEDIT" then do - self~addUserMsg("DefTreeEditStarter", 0x0000004E, "0xFFFFFFFF", id, "0xFFFFFFFF", -410, "0xFFFFFFFF") - lp = -411 - msgToRise = "DefTreeEditHandler" - end - when type = "KEYDOWN" then lp = -412 - otherwise return -1 - end - - tag = 0 - if lp == -405 | lp == -406 then do - if willReply then tag = 0x02000006 - else tag = 0x00000006 - end - - return self~addUserMsg(msgToRise, 0x0000004E, "0xFFFFFFFF", id, "0xFFFFFFFF", lp, "0xFFFFFFFF", tag) - - ::method connectTabEvent use strict arg id, type, msgToRise = "", willReply = .false if \ id~dataType("W") then id = self~resolveSymbolicId(id) @@ -326,6 +292,7 @@ return self~addUserMsg(msgToRise, 0x00000115, "0xFFFFFFFF", wp, "0x0000FFFF", hwnd, "0xFFFFFFFF") /* WM_VSCROLL */ +::method connectTreeViewEvent external "LIBRARY oodialog en_connectTreeViewEvent" ::method connectListViewEvent external "LIBRARY oodialog en_connectListViewEvent" ::method connectDateTimePickerEvent external "LIBRARY oodialog en_connectDateTimePickerEvent" ::method connectMonthCalendarEvent external "LIBRARY oodialog en_connectMonthCalendarEvent" Modified: ooDialog/trunk/ooDialog/oodMessaging.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodMessaging.cpp 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/ooDialog/oodMessaging.cpp 2012-10-11 02:58:09 UTC (rev 8499) @@ -896,20 +896,23 @@ * @param t Error type. * * @return False always. - * TODO this doc is not - * correct, need to edit. + * * @remarks For all the original types of ooDialog dialogs (4.0.1 and * previous,) DestroyWindow() causes a WM_DESTROY message to reach * RexxDlgProc(). The dialog procedure then posts a quit message, we * fall out of the message loop and things unwind cleanly. * - * Setting abnormalHalt causes ensureFinished() to be invoked which + * Setting abnormalHalt to true ensures we don't invoke leaving() and + * that the dialog return gets set to 2. Calling ensureFinished() * terminates the thread waiting on the finished instance variable. * * This works fine for modeless property sheets, but modal property * sheets hang. The abortPropertySheet() essentially does a * programmatic close and prevents any of the property sheet pages * from nixing the close. + * + * Note that if we do not call ensureFinished here, we get a crash in + * the Window message processing loop. */ BOOL endDialogPremature(pCPlainBaseDialog pcpbd, HWND hDlg, DlgProcErrType t) { @@ -955,7 +958,7 @@ abortPropertySheet((pCPropertySheetDialog)pcpbd->dlgPrivate, hDlg, t); return FALSE; } - //ensureFinished(pcpbd, pcpbd->dlgProcContext, TheTrueObj); + ensureFinished(pcpbd, pcpbd->dlgProcContext, TheTrueObj); } DestroyWindow(hDlg); @@ -1692,6 +1695,36 @@ break; } + case LVN_GETINFOTIP : + { + NMLVGETINFOTIP *tip = (LPNMLVGETINFOTIP)lParam; + + RexxObjectPtr item = c->Int32(tip->iItem); + RexxObjectPtr text = tip->dwFlags == 0 ? c->String(tip->pszText) : c->NullString(); + RexxObjectPtr len = c->Int32(tip->cchTextMax - 1); + + RexxArrayObject args = c->ArrayOfFour(idFrom, item, text, len); + + RexxObjectPtr msgReply = c->SendMessage(pcpbd->rexxSelf, methodName, args); + + if ( msgReplyIsGood(c, pcpbd, msgReply, methodName, false) ) + { + CSTRING newText = c->ObjectToStringValue(msgReply); + if ( strlen(newText) > 0 ) + { + _snprintf(tip->pszText, tip->cchTextMax - 1, "%s", newText); + } + } + + c->ReleaseLocalReference(idFrom); + c->ReleaseLocalReference(item); + c->ReleaseLocalReference(text); + c->ReleaseLocalReference(len); + c->ReleaseLocalReference(args); + + return ReplyTrue; + } + case LVN_KEYDOWN : { RexxObjectPtr rxLV = createControlFromHwnd(c, pcpbd, ((NMHDR *)lParam)->hwndFrom, winListView, true); @@ -2079,6 +2112,39 @@ return ReplyTrue; } + case TVN_GETINFOTIP : + { + NMTVGETINFOTIP *tip = (LPNMTVGETINFOTIP)lParam; + + RexxObjectPtr handle = pointer2string(c, tip->hItem); + RexxObjectPtr userData = tip->lParam ? (RexxObjectPtr)tip->lParam : TheNilObj; + RexxObjectPtr text = c->String(tip->pszText - 1); + RexxObjectPtr len = c->Int32(tip->cchTextMax); + + RexxArrayObject args = c->ArrayOfFour(idFrom, handle, text, len); + c->ArrayPut(args, userData, 5); + + RexxObjectPtr msgReply = c->SendMessage(pcpbd->rexxSelf, methodName, args); + + if ( msgReplyIsGood(c, pcpbd, msgReply, methodName, false) ) + { + CSTRING newText = c->ObjectToStringValue(msgReply); + if ( strlen(newText) > 0 ) + { + _snprintf(tip->pszText, tip->cchTextMax - 1, "%s", newText); + } + } + + c->ReleaseLocalReference(idFrom); + c->ReleaseLocalReference(handle); + c->ReleaseLocalReference(userData); + c->ReleaseLocalReference(text); + c->ReleaseLocalReference(len); + c->ReleaseLocalReference(args); + + return ReplyTrue; + } + default : break; } @@ -3095,6 +3161,89 @@ /** + * Convert a keyword to the proper tree-view notification code. + * + * + */ +static bool keyword2tvn(RexxMethodContext *c, CSTRING keyword, uint32_t *code, uint32_t *tag, bool *isDefEdit, logical_t willReply) +{ + uint32_t tvn = 0; + + *isDefEdit = false; + *tag = 0; + + if ( StrCmpI(keyword, "SELCHANGING") == 0 ) tvn = TVN_SELCHANGING; + else if ( StrCmpI(keyword, "SELCHANGED" ) == 0 ) tvn = TVN_SELCHANGED; + else if ( StrCmpI(keyword, "BEGINDRAG" ) == 0 ) tvn = TVN_BEGINDRAG; + else if ( StrCmpI(keyword, "BEGINRDRAG" ) == 0 ) tvn = TVN_BEGINRDRAG; + else if ( StrCmpI(keyword, "DELETE" ) == 0 ) tvn = TVN_DELETEITEM; + else if ( StrCmpI(keyword, "BEGINEDIT" ) == 0 ) tvn = TVN_BEGINLABELEDIT; + else if ( StrCmpI(keyword, "ENDEDIT" ) == 0 ) tvn = TVN_ENDLABELEDIT; + else if ( StrCmpI(keyword, "KEYDOWN" ) == 0 ) tvn = TVN_KEYDOWN; + else if ( StrCmpI(keyword, "DEFAULTEDIT") == 0 ) *isDefEdit = true; + else if ( StrCmpI(keyword, "EXPANDING" ) == 0 ) + { + tvn = TVN_ITEMEXPANDING; + *tag = TAG_TREEVIEW; + } + else if ( StrCmpI(keyword, "EXPANDED") == 0 ) + { + tvn = TVN_ITEMEXPANDED; + *tag = TAG_TREEVIEW; + } + else if ( StrCmpI(keyword, "GETINFOTIP") == 0 ) + { + tvn = TVN_GETINFOTIP; + *tag = TAG_TREEVIEW | TAG_REPLYFROMREXX; + } + else + { + return false; + } + + if ( *tag != 0 && willReply ) + { + *tag = *tag | TAG_REPLYFROMREXX; + } + + *code = tvn; + return true; +} + + +/** + * Convert a tree view notification code and tag to a method name. + */ +inline CSTRING tvn2name(uint32_t tvn, uint32_t tag) +{ + switch ( tvn ) + { + case TVN_SELCHANGING : return "onSelChanging"; + case TVN_SELCHANGED : return "onSelChanged"; + case TVN_BEGINDRAG : return "onBeginDrag"; + case TVN_BEGINRDRAG : return "onBeginRDrag"; + case TVN_DELETEITEM : return "onDeleteItem"; + case TVN_BEGINLABELEDIT : return "onBeginLabelEdit"; + case TVN_ENDLABELEDIT : return "onEndLabelEdit"; + case TVN_ITEMEXPANDING : return "onItemExpanding"; + case TVN_ITEMEXPANDED : return "onItemExpanded"; + case TVN_GETINFOTIP : return "onGetInfoTip"; + case TVN_KEYDOWN : + if ( tag & TAG_TREEVIEW ) + { + return "onKeyDownEx"; + } + else + { + return "onKeydown"; + } + + } + return "onTVN"; +} + + +/** * Convert a keyword to the proper list view notification code. * * @@ -3158,6 +3307,11 @@ lvn = LVN_ITEMCHANGED; *tag = TAG_LISTVIEW | TAG_STATECHANGED | TAG_SELECTCHANGED | TAG_FOCUSCHANGED; } + else if ( StrCmpI(keyword, "GETINFOTIP") == 0 ) + { + lvn = LVN_GETINFOTIP; + *tag = TAG_LISTVIEW | TAG_REPLYFROMREXX; + } else { return false; @@ -3190,6 +3344,7 @@ case LVN_BEGINDRAG : return "onBegindrag"; case LVN_BEGINRDRAG : return "onBeginrdrag"; case LVN_ITEMACTIVATE : return "onActivate"; + case LVN_GETINFOTIP : return "onGetInfoTip"; case NM_CLICK : return "onClick"; case LVN_KEYDOWN : if ( tag & TAG_LISTVIEW ) @@ -4863,6 +5018,110 @@ } +/** EventNotification::connectTreeViewEvent() + * + * Connects a Rexx dialog method with a tree-view event. + * + * @param rxID The resource ID of the dialog control. Can be numeric + * or symbolic. + * + * @param event Keyword specifying which event to connect. Keywords at + * this time: + * + * SELCHANGING + * SELCHANGED + * EXPANDING + * EXPANDED + * BEGINDRAG + * BEGINRDRAG + * DELETE + * BEGINEDIT + * ENDEDIT + * DEFAULTEDIT + * KEYDOWN + * GETINFOTIP + * + * + * @param methodName [OPTIONAL] The name of the method to be invoked in the + * Rexx dialog. If this argument is omitted then the + * method name is constructed by prefixing the event + * keyword with 'on'. For instance onExpanding. + * + * @param willReply [OPTIONAL] Specifies if the method invocation should be + * direct or indirect. With a direct invocation, the + * interpreter waits in the Windows message loop for the + * return from the Rexx method. With indirect, the Rexx + * method is invoked through ~startWith(), which of course + * returns immediately. + * + * For tree-views, at this time, the default is false, i.e. + * the Rexx programmer needs to specify that she wants to + * reply. This could change if new key words are added. + * + * @return 0 for no error, -1 for a bad resource ID or incorrect event keyword, + * 1 if the event could not be connected. The event can not be + * connected if there is a problem with the message table, full or out + * of memory error. + * + * @remarks For the current keywords, if a symbolic ID is used and it can + * not be resolved to a numeric number -1 has to be returned for + * backwards compatibility. Essentially, except for the keywords + * listed below, for this method, all behaviour needs to be + * pre-4.2.0. + * + * EXPANDING / EXPANDED The willReply request is honored + * + * INFOTIP new keyword - will reply is always set to true for this + * keyword. + */ +RexxMethod5(RexxObjectPtr, en_connectTreeViewEvent, RexxObjectPtr, rxID, CSTRING, event, + OPTIONAL_CSTRING, methodName, OPTIONAL_logical_t, willReply, CSELF, pCSelf) +{ + pCEventNotification pcen = (pCEventNotification)pCSelf; + + int32_t id; + if ( ! oodSafeResolveID(&id, context, pcen->rexxSelf, rxID, -1, 1, true) ) + { + return TheNegativeOneObj; + } + + uint32_t tag = 0; + bool isDefEdit = false; + uint32_t notificationCode; + + if ( ! keyword2tvn(context, event, ¬ificationCode, &tag, &isDefEdit, willReply) ) + { + return TheNegativeOneObj; + } + + // Deal with DEFAULTEDIT separately. + if ( isDefEdit ) + { + if ( ! addNotifyMessage(pcen, context, id, 0xFFFFFFFF, TVN_BEGINLABELEDIT, 0xFFFFFFFF, "DefTreeEditStarter", 0) ) + { + return TheNegativeOneObj; + } + if ( ! addNotifyMessage(pcen, context, id, 0xFFFFFFFF, TVN_ENDLABELEDIT, 0xFFFFFFFF, "DefTreeEditHandler", 0) ) + { + return TheNegativeOneObj; + } + return TheZeroObj; + } + + if ( argumentOmitted(3) || *methodName == '\0' ) + { + methodName = tvn2name(notificationCode, tag); + } + + if ( addNotifyMessage(pcen, context, id, 0xFFFFFFFF, notificationCode, 0xFFFFFFFF, methodName, tag) ) + { + return TheZeroObj; + } + + return TheOneObj; +} + + /** EventNotification::connectUpDownEvent() * * Connects a Rexx dialog method with an up down control event. Modified: ooDialog/trunk/ooDialog/oodPackageEntry.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-10-11 02:58:09 UTC (rev 8499) @@ -537,6 +537,7 @@ REXX_METHOD_PROTOTYPE(en_connectEachSBEvent); REXX_METHOD_PROTOTYPE(en_connectAllSBEvents); REXX_METHOD_PROTOTYPE(en_connectListViewEvent); +REXX_METHOD_PROTOTYPE(en_connectTreeViewEvent); REXX_METHOD_PROTOTYPE(en_connectDateTimePickerEvent); REXX_METHOD_PROTOTYPE(en_connectMonthCalendarEvent); REXX_METHOD_PROTOTYPE(en_connectUpDownEvent); @@ -1507,6 +1508,7 @@ REXX_METHOD(en_connectEachSBEvent, en_connectEachSBEvent), REXX_METHOD(en_connectAllSBEvents, en_connectAllSBEvents), REXX_METHOD(en_connectListViewEvent, en_connectListViewEvent), + REXX_METHOD(en_connectTreeViewEvent, en_connectTreeViewEvent), REXX_METHOD(en_connectDateTimePickerEvent, en_connectDateTimePickerEvent), REXX_METHOD(en_connectMonthCalendarEvent, en_connectMonthCalendarEvent), REXX_METHOD(en_connectUpDownEvent, en_connectUpDownEvent), Modified: ooDialog/trunk/ooDialog/oodUser.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodUser.cpp 2012-10-10 03:12:08 UTC (rev 8498) +++ ooDialog/trunk/ooDialog/oodUser.cpp 2012-10-11 02:58:09 UTC (rev 8499) @@ -718,6 +718,7 @@ if ( StrStrI(opts, "EDIT" ) != NULL ) style |= TVS_EDITLABELS; if ( StrStrI(opts, "BUTTONS" ) != NULL ) style |= TVS_HASBUTTONS; if ( StrStrI(opts, "LINES" ) != NULL ) style |= TVS_HASLINES; + if ( StrStrI(opts, "INFOTIP" ) != NULL ) style |= TVS_INFOTIP; if ( StrStrI(opts, "ATROOT" ) != NULL ) style |= TVS_LINESATROOT; if ( StrStrI(opts, "SHOWSELALWAYS") != NULL ) style |= TVS_SHOWSELALWAYS; return style; |
From: <mie...@us...> - 2012-10-13 00:02:02
|
Revision: 8503 http://sourceforge.net/p/oorexx/code-0/8503 Author: miesfeld Date: 2012-10-13 00:01:59 +0000 (Sat, 13 Oct 2012) Log Message: ----------- #419 Add Tooltip control See ticket [Feature-requests:#419] Modified Paths: -------------- ooDialog/trunk/MakeFile ooDialog/trunk/ooDialog/PlainBaseDialog.cls ooDialog/trunk/ooDialog/build_ooDialog_cls.rex ooDialog/trunk/ooDialog/ooDialog.cpp ooDialog/trunk/ooDialog/ooDialog.hpp ooDialog/trunk/ooDialog/oodControl.cpp ooDialog/trunk/ooDialog/oodControl.hpp ooDialog/trunk/ooDialog/oodMessaging.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp ooDialog/trunk/ooDialog/oodialog.mak Added Paths: ----------- ooDialog/trunk/ooDialog/ToolTip.cls ooDialog/trunk/ooDialog/oodToolTip.cpp Modified: ooDialog/trunk/MakeFile =================================================================== --- ooDialog/trunk/MakeFile 2012-10-11 03:33:40 UTC (rev 8502) +++ ooDialog/trunk/MakeFile 2012-10-13 00:01:59 UTC (rev 8503) @@ -130,8 +130,8 @@ $(OOD_OODIALOGSRC)\DeprecatedClasses.cls $(OOD_OODIALOGSRC)\DialogControls.cls $(OOD_OODIALOGSRC)\DialogExtensions.cls \ $(OOD_OODIALOGSRC)\DynamicDialog.cls $(OOD_OODIALOGSRC)\EventNotification.cls $(OOD_OODIALOGSRC)\ListView.cls \ $(OOD_OODIALOGSRC)\Menu.cls $(OOD_OODIALOGSRC)\PlainBaseDialog.cls $(OOD_OODIALOGSRC)\RcDialog.cls \ - $(OOD_OODIALOGSRC)\ResDialog.cls $(OOD_OODIALOGSRC)\UserDialog.cls $(OOD_OODIALOGSRC)\TreeView.cls \ - $(OOD_OODIALOGSRC)\UtilityClasses.cls + $(OOD_OODIALOGSRC)\ResDialog.cls $(OOD_OODIALOGSRC)\UserDialog.cls $(OOD_OODIALOGSRC)\ToolTip.cls \ + $(OOD_OODIALOGSRC)\T |
From: <mie...@us...> - 2012-10-27 04:40:04
|
Revision: 8540 http://sourceforge.net/p/oorexx/code-0/8540 Author: miesfeld Date: 2012-10-27 04:40:00 +0000 (Sat, 27 Oct 2012) Log Message: ----------- ooDialog - fix problem with blocked thread in the Paid Holidays example Modified Paths: -------------- ooDialog/trunk/MakeFile ooDialog/trunk/examples/controls/PaidHolidays.rex Modified: ooDialog/trunk/MakeFile =================================================================== --- ooDialog/trunk/MakeFile 2012-10-26 15:22:59 UTC (rev 8539) +++ ooDialog/trunk/MakeFile 2012-10-27 04:40:00 UTC (rev 8540) @@ -54,7 +54,7 @@ # This setting is for my specific machine and should be changed or commented out # when building -REXX_HOME = C:\Rexx\static.ooRexx.4.1.0.release +#REXX_HOME = C:\Rexx\static.ooRexx.4.1.0.release # Define DEBUG on the command line, or here, to build a debug version. By # default non- debug versions are built. I.e. nMake DEBUG=1 @@ -69,7 +69,7 @@ ! error Build error: REXX_HOME not defined !endif -REXX_LIBS = $(REXX_HOME)\api\rexx.lib $(REXX_HOME)\api\rexxapi.lib +REXX_LIBS = "$(REXX_HOME)\api\rexx.lib" "$(REXX_HOME)\api\rexxapi.lib" # Generate the compiler information, plus OOD_ROOT_DIR. Quit if there is an # error. Modified: ooDialog/trunk/examples/controls/PaidHolidays.rex =================================================================== --- ooDialog/trunk/examples/controls/PaidHolidays.rex 2012-10-26 15:22:59 UTC (rev 8539) +++ ooDialog/trunk/examples/controls/PaidHolidays.rex 2012-10-27 04:40:00 UTC (rev 8540) @@ -201,7 +201,7 @@ -- This function returns an array of .DayState objects for the specified months. -- A day state object specifies which days in a month should be bolded. -::method getDayStateArray private +::method getDayStateArray private unguarded use strict arg startMonth, count -- Create the array to hold the .DayState objects. @@ -227,7 +227,7 @@ -- This function initalizes a .DayState object to the proper value depending on -- the month specified. -::method getDayState private +::method getDayState private unguarded use strict arg month select |
From: <mie...@us...> - 2012-10-27 05:01:44
|
Revision: 8541 http://sourceforge.net/p/oorexx/code-0/8541 Author: miesfeld Date: 2012-10-27 05:01:42 +0000 (Sat, 27 Oct 2012) Log Message: ----------- ooDialog - update release notes Modified Paths: -------------- ooDialog/trunk/MakeFile ooDialog/trunk/doc/ReleaseNotes.txt Modified: ooDialog/trunk/MakeFile =================================================================== --- ooDialog/trunk/MakeFile 2012-10-27 04:40:00 UTC (rev 8540) +++ ooDialog/trunk/MakeFile 2012-10-27 05:01:42 UTC (rev 8541) @@ -54,7 +54,7 @@ # This setting is for my specific machine and should be changed or commented out # when building -#REXX_HOME = C:\Rexx\static.ooRexx.4.1.0.release +REXX_HOME = C:\Rexx\static.ooRexx.4.1.0.release # Define DEBUG on the command line, or here, to build a debug version. By # default non- debug versions are built. I.e. nMake DEBUG=1 Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-10-27 04:40:00 UTC (rev 8540) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-10-27 05:01:42 UTC (rev 8541) @@ -1,6 +1,14 @@ - Release Notes ooDialog 4.2.1 - ============================ + Release Notes ooDialog 4.2.1 (preview) + ====================================== +NOTE: This preview version is a SNAPSHOT of the current development in + ooDialog. It is not a beta release, or even an alpha release. + The build is placed here to allow to interested parties to toy + with some of the new features coming up. Devlopment work is still + on-going and new interfaces are not guarenteed. Method names and + or method arguments of features currently in development may + change before a final release. + The ooDialog 4.2.1 release is focused on improvements to the ListView class in ooDialog. In addition to bug fixes, this release contains a number of enhancement to the list-view implementation in ooDialog. @@ -52,7 +60,18 @@ * #1116 Debug print outs left in ooDialog 4.2.0 +* #1117 Method handler passed wrong argument for TreeView EXPANDING + event +* #1121 ooDialog appcrash running forward class(super) continue + +* #1124 ooDialog - failed to locate .h file message incorrect + +* #1126 ooDialog - args sent to the HELP event handler incorrect + +* #1128 ooDialog UtilityClasses.cls: typo + + Feature Requests in ooDialog: ----------------------------- @@ -65,7 +84,18 @@ * #484 ooDialog setColor methods should not be restricted to the 19 palette indexes +* #485 Treeview itemData +* #486 ooDialog - the TreeView Expanding event should allow a veto + +* #487 ooDialog - It would be nice if the TreeView class had a way + to do custom sorting + +* #489 ooDialog - TreeView class should support info tips + +* #490 ooDialog - ListView class should support info tips + + New Functionality in ooDialog: ------------------------------ |
From: <mie...@us...> - 2012-10-27 21:43:22
|
Revision: 8543 http://sourceforge.net/p/oorexx/code-0/8543 Author: miesfeld Date: 2012-10-27 21:43:19 +0000 (Sat, 27 Oct 2012) Log Message: ----------- ooDialog - The newly added TreeView::getItemText() method should have been named itemText() to match the similar method in the ListView class. The implementation for an alternative event connection for the KEYDOWN event for the ListView was started, but not completed. The implementaion supplies additional arguments to the event handler. In addition the TreeView class was meant to also use this implmentation. The keyword, KEYDOWNEX is used to signal the programmer wants to use the alternative implmentation. Fix this up. Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/ooDialog/TreeView.cls ooDialog/trunk/ooDialog/oodMessaging.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp ooDialog/trunk/ooDialog/oodTreeView.cpp Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-10-27 15:49:20 UTC (rev 8542) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-10-27 21:43:19 UTC (rev 8543) @@ -71,7 +71,9 @@ * #1128 ooDialog UtilityClasses.cls: typo +* #1138 MessageDialog: Failure in system service + Feature Requests in ooDialog: ----------------------------- @@ -179,6 +181,7 @@ find() getItemData() +itemText() removeItemData() setItemData() @@ -202,7 +205,17 @@ itemInfo() modify() +In the EventNotification class: +connectListViewItem() + + * the KEYDOWNEX event is added. + +connectTreeViewItem() + + * the KEYDOWNEX event is added. + + New samples: ------------ Modified: ooDialog/trunk/ooDialog/TreeView.cls =================================================================== --- ooDialog/trunk/ooDialog/TreeView.cls 2012-10-27 15:49:20 UTC (rev 8542) +++ ooDialog/trunk/ooDialog/TreeView.cls 2012-10-27 21:43 |
From: <mie...@us...> - 2012-11-03 19:17:09
|
Revision: 8555 http://sourceforge.net/p/oorexx/code-0/8555 Author: miesfeld Date: 2012-11-03 19:17:06 +0000 (Sat, 03 Nov 2012) Log Message: ----------- ooDialog: #493 ooDialog - TreeView begin / end label editing could be improved See ticket [Feature-requests:#493] #494 ooDialog - ListView begin / end label editing events could be improved. See ticket [Feature-requests:#494] #419 Add Tooltip control See ticket [Feature-requests:#419] Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/ooDialog/APICommon.cpp ooDialog/trunk/ooDialog/EventNotification.cls ooDialog/trunk/ooDialog/ListView.cls ooDialog/trunk/ooDialog/ToolTip.cls ooDialog/trunk/ooDialog/TreeView.cls ooDialog/trunk/ooDialog/ooDialog.hpp ooDialog/trunk/ooDialog/oodControl.cpp ooDialog/trunk/ooDialog/oodControl.hpp ooDialog/trunk/ooDialog/oodMessaging.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp ooDialog/trunk/ooDialog/oodToolTip.cpp ooDialog/trunk/ooDialog/oodTreeView.cpp ooDialog/trunk/ooDialog/oodUser.cpp ooDialog/trunk/ooDialog/oodViewControls.cpp Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-11-03 19:17:06 UTC (rev 8555) @@ -81,6 +81,8 @@ * #130 OODialog List Control Class Activate sort headers +* #420 Would like to have an AddButtonStem method. + * #483 ooDialog setColor and dialog background improvements * #484 ooDialog setColor methods should not be restricted to the 19 @@ -93,6 +95,8 @@ * #487 ooDialog - It would be nice if the TreeView class had a way to do custom sorting +* #488 ooDialog - TreeView class needs a itemText method + * #489 ooDialog - TreeView class should support info tips * #490 ooDialog - ListView class should support info tips Modified: ooDialog/trunk/ooDialog/APICommon.cpp =================================================================== --- ooDialog/trunk/ooDialog/APICommon.cpp 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/APICommon.cpp 2012-11-03 19:17:06 UTC (rev 8555) @@ -716,9 +716,9 @@ return NULLOBJECT; } -RexxObjectPtr wrongRangeException(RexxThreadContext *c, size_t pos, uint32_t min, uint32_t max, uint32_t actual) +RexxObjectPtr wrongRangeException(RexxMethodContext *c, size_t pos, uint32_t min, uint32_t max, uint32_t actual) { - return wrongRangeException(c, pos, min, max, c->UnsignedInt32(actual)); + return wrongRangeException(c->threadContext, pos, min, max, c->UnsignedInt32(actual)); } RexxObjectPtr wrongArgValueException(RexxThreadContext *c, size_t pos, const char *list, RexxObjectPtr actual) Modified: ooDialog/trunk/ooDialog/EventNotification.cls =================================================================== --- ooDialog/trunk/ooDialog/EventNotification.cls 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/EventNotification.cls 2012-11-03 19:17:06 UTC (rev 8555) @@ -298,23 +298,6 @@ ::method connectDateTimePickerEvent external "LIBRARY oodialog en_connectDateTimePickerEvent" ::method connectMonthCalendarEvent external "LIBRARY oodialog en_connectMonthCalendarEvent" ::method connectUpDownEvent external "LIBRARY oodialog en_connectUpDownEvent" - -::method defListEditStarter - use arg id, dummy, category - if arg(3, 'O') then lc = self~newListView(id) - else lc = self~newListView(id, category) - if lc \= .nil then lc~subclassEdit - -::method defListEditHandler - use arg id, item, newText, category - if arg(3, 'O') then return - if arg(4, 'O') then lc = self~newListView(id) - else lc = self~newListView(id, category) - if lc \= .nil then do - lc~modify(item, 0, newText) - lc~restoreEditClass - end - ::method defListDragHandler use arg id, item, pt lc = self~newListView(id) Modified: ooDialog/trunk/ooDialog/ListView.cls =================================================================== --- ooDialog/trunk/ooDialog/ListView.cls 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/ListView.cls 2012-11-03 19:17:06 UTC (rev 8555) @@ -156,6 +156,7 @@ ::method getItemData unguarded external "LIBRARY oodialog lv_getItemData" ::method getItemInfo unguarded external "LIBRARY oodialog lv_getItemInfo" ::method getItemPos unguarded external "LIBRARY oodialog lv_getItemPos" +::method getToolTips unguarded external "LIBRARY oodialog generic_getToolTips" ::method getSubitem unguarded external "LIBRARY oodialog lv_getSubitem" ::method hasCheckBoxes unguarded external "LIBRARY oodialog lv_hasCheckBoxes" ::method hitTestInfo unguarded external "LIBRARY oodialog lv_hitTestInfo" @@ -228,7 +229,6 @@ ::method removeStyle unguarded external "LIBRARY oodialog lv_addRemoveStyle" ::method replaceExtendedStyle unguarded external "LIBRARY oodialog lv_replaceExtendStyle" ::method replaceStyle unguarded external "LIBRARY oodialog lv_replaceStyle" -::method restoreEditClass unguarded external "LIBRARY oodialog generic_subclassEdit" ::method scroll unguarded use strict arg x = 0, y = 0 return self~sendWinIntMsg(self~LVM_SCROLL, x, y) <> 0 @@ -255,6 +255,7 @@ ::method setItemPos unguarded external "LIBRARY oodialog lv_setItemPos" ::method setItemState unguarded external "LIBRARY oodialog lv_setItemState" ::method setItemText unguarded external "LIBRARY oodialog lv_setItemText" +::method setToolTips unguarded external "LIBRARY oodialog generic_setToolTips" ::method smallSpacing unguarded return self~sendWinIntMsg(self~LVM_GETITEMSPACING, 1, 0) @@ -268,7 +269,6 @@ return self~stringWidthPx(text) / self~factorX ::method stringWidthPx unguarded external "LIBRARY oodialog lv_stringWidthPx" -::method subclassEdit unguarded external "LIBRARY oodialog generic_subclassEdit" ::method textBkColor unguarded external "LIBRARY oodialog lv_getColor" ::method "textBkColor=" unguarded external "LIBRARY oodialog lv_setColor" ::method textColor unguarded external "LIBRARY oodialog lv_getColor" @@ -291,6 +291,9 @@ return self~removeImageList(.nil, 1) -- DEPRECATED +::method restoreEditClass + +-- DEPRECATED ::method setImages unguarded external "LIBRARY oodialog lv_setImageList" -- DEPRECATED @@ -299,6 +302,8 @@ newArgs[4] = 1 forward message 'setImageList' arguments (newArgs) +-- DEPRECATED +::method subclassEdit ::class 'LvItem' public -- Do not document for 4.2.0 ::method init external "LIBRARY oodialog lvi_init" Modified: ooDialog/trunk/ooDialog/ToolTip.cls =================================================================== --- ooDialog/trunk/ooDialog/ToolTip.cls 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/ToolTip.cls 2012-11-03 19:17:06 UTC (rev 8555) @@ -50,16 +50,20 @@ ::method addToolRect unguarded external "LIBRARY oodialog tt_addToolRect" ::method adjustRect unguarded external "LIBRARY oodialog tt_adjustRect" ::method delTool unguarded external "LIBRARY oodialog tt_delTool" +::method enumTools unguarded external "LIBRARY oodialog tt_enumTools" ::method getCurrentToolInfo unguarded external "LIBRARY oodialog tt_getCurrentToolInfo" +::method getToolCount unguarded external "LIBRARY oodialog tt_getToolCount" ::method getToolInfo unguarded external "LIBRARY oodialog tt_getToolInfo" ::method popUp unguarded external "LIBRARY oodialog tt_popUp" ::method setMaxTipWidth unguarded external "LIBRARY oodialog tt_setMaxTipWidth" ::method trackActivate unguarded external "LIBRARY oodialog tt_trackActivate" ::method trackPosition unguarded external "LIBRARY oodialog tt_trackPosition" +::method useRelayEvent unguarded external "LIBRARY oodialog tt_useRelayEvent" ::class 'ToolInfo' public ::method fromID class external "LIBRARY oodialog ti_fromID_cls" +::method fromIdEx class external "LIBRARY oodialog ti_fromIdEx_cls" ::method init external "LIBRARY oodialog ti_init" ::method unInit external "LIBRARY oodialog ti_unInit" Modified: ooDialog/trunk/ooDialog/TreeView.cls =================================================================== --- ooDialog/trunk/ooDialog/TreeView.cls 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/TreeView.cls 2012-11-03 19:17:06 UTC (rev 8555) @@ -111,6 +111,7 @@ ::method firstVisible unguarded external "LIBRARY oodialog tv_getSpecificItem" ::method getImageList unguarded external "LIBRARY oodialog tv_getImageList" ::method getItemData unguarded external "LIBRARY oodialog tv_getItemData" +::method getToolTips unguarded external "LIBRARY oodialog generic_getToolTips" ::method hitTest unguarded forward message "hitTestInfo" continue info = result @@ -183,12 +184,12 @@ ::method previous unguarded external "LIBRARY oodialog tv_getNextItem" ::method previousVisible unguarded external "LIBRARY oodialog tv_getNextItem" ::method removeItemData external "LIBRARY oodialog tv_removeItemData" -::method restoreEditClass external "LIBRARY oodialog generic_subclassEdit" ::method root unguarded external "LIBRARY oodialog tv_getSpecificItem" ::method select unguarded external "LIBRARY oodialog tv_selectItem" ::method selected unguarded external "LIBRARY oodialog tv_getSpecificItem" ::method setImageList unguarded external "LIBRARY oodialog tv_setImageList" ::method setItemData unguarded external "LIBRARY oodialog tv_setItemData" +::method setToolTips unguarded external "LIBRARY oodialog generic_setToolTips" -- The old code did not have recurse arg and had a comment saying "recursive not yet supported" -- Although MSDN documents this message as recursively sorting the children if WPARAM is true, @@ -198,7 +199,6 @@ return self~sendWinHandle2Msg(self~TVM_SORTCHILDREN, recurse, hItem) ::method sortChildrenCB external "LIBRARY oodialog tv_sortChildrenCB" -::method subclassEdit external "LIBRARY oodialog generic_subclassEdit" ::method toggle unguarded external "LIBRARY oodialog tv_expand" ::method visibleItems unguarded @@ -207,11 +207,17 @@ -- DEPRECATED +::method removeImages unguarded + return self~setImageList(.nil, 0) + +-- DEPRECATED +::method restoreEditClass + +-- DEPRECATED ::method setImages unguarded external "LIBRARY oodialog tv_setImageList" -- DEPRECATED -::method removeImages unguarded - return self~setImageList(.nil, 0) +::method subclassEdit ::class 'TvCustomDrawSimple' public Modified: ooDialog/trunk/ooDialog/ooDialog.hpp =================================================================== --- ooDialog/trunk/ooDialog/ooDialog.hpp 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/ooDialog.hpp 2012-11-03 19:17:06 UTC (rev 8555) @@ -179,6 +179,11 @@ #define TAG_CD_TRACKBAR 0x00002000 #define TAG_CD_TREEVIEW 0x00004000 +// When combined with the CTRL flag of a dialog control, (nothing else,) +// indicates the event handler should be invoked exactly the same as in old +// ooDialog (pre 4.2.0.) +#define TAG_PRESERVE_OLD 0x00100000 + /** * The last byte is for, well 'extra' information. Use TAG_EXTRAMASK to * isolate the byte. @@ -746,6 +751,20 @@ typedef SubClassData *pSubClassData; +// A specific structure used for subclassing controls to use with the tool tip +// relay event. +typedef struct _relayEventData { + pCPlainBaseDialog pcpbd; // The Rexx owner dialog CSelf + pCDialogControl pcdc; // The Rexx control dialog CSelf + HWND hCtrl; // Window handle of subclassed control. + HWND hToolTip; // Window handle of tool tip + RexxObjectPtr rxToolTip; + char *method; // Rexx method to invoke + uint32_t id; // Resource ID of subclassed control. +} RelayEventData; +typedef RelayEventData *pRelayEventData; + + /* Struct for the DynamicDialog object CSelf. */ typedef struct _ddCSelf { pCPlainBaseDialog pcpbd; Modified: ooDialog/trunk/ooDialog/oodControl.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodControl.cpp 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/oodControl.cpp 2012-11-03 19:17:06 UTC (rev 8555) @@ -687,6 +687,36 @@ /** + * If the user stores a Rexx object in the user data storage of a dialog + * control, the Rexx object could be garbage collected because no Rexx object + * has a reference to it. To prevent that we put the Rexx object in a bag that + * is an attribute of the dialog control object. + * + * @param c + * @param pcdc + * @param data + * + * @notes This function could have been called maybeProtectControlUserData() + * because it only stores a Rexx object if the data is not .nil and not + * null. + */ +void protectControlUserData(RexxMethodContext *c, pCDialogControl pcdc, RexxObjectPtr data) +{ + if ( data != TheNilObj && data != NULLOBJECT ) + { + if ( pcdc->rexxBag == NULL ) + { + c->SendMessage1(pcdc->rexxSelf, "PUTINBAG", data); + } + else + { + c->SendMessage1(pcdc->rexxBag, "PUT", data); + } + } +} + + +/** * Removes a Rexx object from the dialog control's Rexx bag. * * @param c @@ -703,36 +733,55 @@ /** - * If the user stores a Rexx object in the user data storage of a dialog - * control, the Rexx object could be garbage collected because no Rexx object - * has a reference to it. To prevent that we put the Rexx object in a bag that - * is an attribute of the dialog control object. + * Protects some Rexx object related to a dialog control from garbage + * collection by putting it in a Rexx bag. * + * This is similar to protectControlUserData(), but more generic. For + * instance, it is used for ToolTip objects of a list-view or tree-view. + * * @param c * @param pcdc - * @param data + * @param obj * - * @notes This function could have been called maybeProtectControlUserData() - * because it only stores a Rexx object if the data is not .nil and not - * null. + * @notes */ -void protectControlUserData(RexxMethodContext *c, pCDialogControl pcdc, RexxObjectPtr data) +void protectControlObject(RexxMethodContext *c, pCDialogControl pcdc, RexxObjectPtr obj) { - if ( data != TheNilObj && data != NULLOBJECT ) + if ( obj != TheNilObj && obj != NULLOBJECT ) { if ( pcdc->rexxBag == NULL ) { - c->SendMessage1(pcdc->rexxSelf, "PUTINBAG", data); + c->SendMessage1(pcdc->rexxSelf, "PUTINBAG", obj); } else { - c->SendMessage1(pcdc->rexxBag, "PUT", data); + c->SendMessage1(pcdc->rexxBag, "PUT", obj); } } } /** + * Removes all instances of a single Rexx object from this dialog control's Rexx + * bag. + * + * @param c + * @param pcdc + * @param oldUserData + * + * @note We use remove all here to remove all of the specified items in the + * bag. + */ +void unProtectControlObject(RexxMethodContext *c, pCDialogControl pcdc, RexxObjectPtr obj) +{ + if ( obj != TheNilObj && obj != NULLOBJECT && pcdc->rexxBag != NULLOBJECT ) + { + c->SendMessage1(pcdc->rexxBag, "REMOVEALL", obj); + } +} + + +/** * Methods for the .DialogControl class. */ #define DIALOGCONTROL_CLASS "DialogControl" @@ -2292,3 +2341,118 @@ return TheNilObj; } + + +/** + * Generic methods for the dialog control classes. These are methods that are + * very similar in two or more controls, enough similar that it doesn't make + * sense to have separate method implmentations. + */ +#define GENERIC_DIALOGCONTROL_METHODS "Generic Methods" + + +/** ListView::getToolTips() + * TreeView::getToolTips() + * + * + * Retrieves the child ToolTip control used by this litst-view or tree-view. + * + * @param None. + * + * @return Returns the tool tip Rexx object, or .nil if there is no tool tip. + * + * @remarks We create a Rexx tool tip object from the returned handle and then + * protect that object. Rather than store the tool tip object in the dialog's + * bag, we put it in the control's bag. We don't check the return from create + * control for TheNilObj because protectControlObect() does that for us. + */ +RexxMethod1(RexxObjectPtr, generic_getToolTips, CSELF, pCSelf) +{ + RexxObjectPtr result = TheNilObj; + + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) + { + goto done_out; + } + + oodControl_t ctrlType = pcdc->controlType; + HWND hTT = NULL; + + if ( ctrlType == winListView ) + { + hTT = ListView_GetToolTips(pcdc->hCtrl); + } + else + { + hTT = TreeView_GetToolTips(pcdc->hCtrl); + } + + if ( hTT == NULL ) + { + goto done_out; + } + + result = createControlFromHwnd(context, pcdc, hTT, ctrlType, false); + protectControlObject(context, pcdc, result); + +done_out: + return result; +} + + +/** ListView::setToolTips() + * TreeView::setToolTips() + * + * Sets the child ToolTip control used by this list-view or tree-view controls + * + * @param None. + * + * @return Returns the previous tool tip, as a Rexx ToolTip object, or .nil if + * there is no previous tool tip. + */ +RexxMethod2(RexxObjectPtr, generic_setToolTips, RexxObjectPtr, toolTip, CSELF, pCSelf) +{ + RexxObjectPtr result = TheNilObj; + + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) + { + goto done_out; + } + if ( ! requiredClass(context->threadContext, toolTip, "ToolTip", 1) ) + { + goto done_out; + } + + oodControl_t ctrlType = pcdc->controlType; + HWND hOldTT = NULL; + + // Rather than put the tool tip object in the dialog bag, we put it in this + // tree-view's bag. + pCDialogControl pcdcTT = controlToCSelf(context, toolTip); + protectControlObject(context, pcdc, toolTip); + + if ( ctrlType == winListView ) + { + hOldTT = ListView_SetToolTips(pcdc->hCtrl, pcdcTT->hCtrl); + } + else + { + hOldTT = TreeView_SetToolTips(pcdc->hCtrl, pcdcTT->hCtrl); + } + if ( hOldTT == NULL ) + { + goto done_out; + } + + // We don't care if .nil is returned because unprotectControlObject() will + // check for TheNilObj and not try to remove it from the bag. + result = createControlFromHwnd(context, pcdc, hOldTT, winToolTip, false); + unProtectControlObject(context, pcdc, result); + +done_out: + return result; +} + + Modified: ooDialog/trunk/ooDialog/oodControl.hpp =================================================================== --- ooDialog/trunk/ooDialog/oodControl.hpp 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/oodControl.hpp 2012-11-03 19:17:06 UTC (rev 8555) @@ -229,8 +229,11 @@ extern bool addSubclassMessage(RexxMethodContext *c, pCDialogControl pcdc, pWinMessageFilter pwmf); extern void unProtectControlUserData(RexxMethodContext *c, pCDialogControl pcdc, RexxObjectPtr oldUserData); extern void protectControlUserData(RexxMethodContext *c, pCDialogControl pcdc, RexxObjectPtr data); +extern void protectControlObject(RexxMethodContext *c, pCDialogControl pcdc, RexxObjectPtr obj); +extern void unProtectControlObject(RexxMethodContext *c, pCDialogControl pcdc, RexxObjectPtr obj); extern RexxObjectPtr createToolTip(RexxMethodContext *context, RexxObjectPtr rxID, CSTRING styleFlags, pCPlainBaseDialog pcpbd); +extern bool tvSubclassEdit(HWND hTV, HWND hEdit, uintptr_t tvID); #define ButtonAtom 0x0080 #define EditAtom 0x0081 Modified: ooDialog/trunk/ooDialog/oodMessaging.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodMessaging.cpp 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/oodMessaging.cpp 2012-11-03 19:17:06 UTC (rev 8555) @@ -1772,6 +1772,151 @@ break; } + case LVN_BEGINLABELEDIT : + { + NMLVDISPINFO *pdi = (NMLVDISPINFO *)lParam; + + if ( (tag & TAG_FLAGMASK) == TAG_PRESERVE_OLD ) + { + // To preserve old behavior for DefListEditStater, we don't need + // to do anything. Otherwise, we need to invoke the named method + // with the old args. + if ( toupper(*methodName) == 'B' ) + { + RexxStringObject mthName = c->String(methodName); + RexxObjectPtr useLess = c->Intptr(lParam); + RexxArrayObject args = c->ArrayOfTwo(idFrom, useLess); + + invokeDispatch(c, pcpbd->rexxSelf, mthName, args); + + c->ReleaseLocalReference(mthName); + c->ReleaseLocalReference(idFrom); + c->ReleaseLocalReference(useLess); + } + return ReplyTrue; + } + + HWND hLv = pdi->hdr.hwndFrom; + HWND hEdit = ListView_GetEditControl(hLv); + + RexxObjectPtr itemID = c->UnsignedInt32(pdi->item.iItem); + RexxObjectPtr rxLv = createControlFromHwnd(c, pcpbd, pdi->hdr.hwndFrom, winListView, true); + RexxObjectPtr rxEdit = createControlFromHwnd(c, pcpbd, hEdit, winEdit, false); + RexxArrayObject args = c->ArrayOfFour(idFrom, itemID, rxEdit, rxLv); + + if ( expectReply ) + { + RexxObjectPtr msgReply = c->SendMessage(pcpbd->rexxSelf, methodName, args); + + msgReply = requiredBooleanReply(c, pcpbd, msgReply, methodName, false); + if ( msgReply == NULL ) + { + return ReplyFalse; + } + + // Return false to let the text be edited, true to disallow it. + // The return from Rexx is true to allow, false to disallow. + setWindowPtr(pcpbd->hDlg, DWLP_MSGRESULT, msgReply == TheTrueObj ? FALSE : TRUE); + } + else + { + RexxStringObject mthName = c->String(methodName); + invokeDispatch(c, pcpbd->rexxSelf, mthName, args); + c->ReleaseLocalReference(mthName); + } + + c->ReleaseLocalReference(idFrom); + c->ReleaseLocalReference(itemID); + if ( rxLv != TheNilObj ) + { + c->ReleaseLocalReference(rxLv); + } + if ( rxEdit != TheNilObj ) + { + c->ReleaseLocalReference(rxEdit); + } + c->ReleaseLocalReference(args); + + return ReplyTrue; + } + + case LVN_ENDLABELEDIT : + { + NMLVDISPINFO *pdi = (NMLVDISPINFO *)lParam; + + if ( (tag & TAG_FLAGMASK) == TAG_PRESERVE_OLD ) + { + // To preserve old behaviour for DefListEditHandler, we don't + // need to do anything except set the reply value. Otherwise, + // we need to invoke the named method with the old args. + if ( toupper(*methodName) == 'B' ) + { + RexxArrayObject args; + + RexxStringObject mthName = c->String(methodName); + RexxObjectPtr itemID = c->UnsignedInt32(pdi->item.iItem); + RexxObjectPtr text = pdi->item.pszText ? c->String(pdi->item.pszText) : NULLOBJECT; + + if ( text != NULLOBJECT ) + { + args = c->ArrayOfThree(idFrom, itemID, text); + invokeDispatch(c, pcpbd->rexxSelf, mthName, args); + + c->ReleaseLocalReference(text); + } + else + { + args = c->ArrayOfTwo(idFrom, itemID); + invokeDispatch(c, pcpbd->rexxSelf, mthName, args); + } + + c->ReleaseLocalReference(mthName); + c->ReleaseLocalReference(idFrom); + c->ReleaseLocalReference(itemID); + } + + setWindowPtr(pcpbd->hDlg, DWLP_MSGRESULT, pdi->item.pszText ? TRUE : FALSE); + return ReplyTrue; + } + + RexxObjectPtr itemID = c->UnsignedInt32(pdi->item.iItem); + RexxObjectPtr text = pdi->item.pszText ? c->String(pdi->item.pszText) : TheNilObj; + RexxObjectPtr rxLV = createControlFromHwnd(c, pcpbd, pdi->hdr.hwndFrom, winListView, true); + RexxArrayObject args = c->ArrayOfFour(idFrom, itemID, text, rxLV); + + if ( expectReply ) + { + RexxObjectPtr msgReply = c->SendMessage(pcpbd->rexxSelf, methodName, args); + + msgReply = requiredBooleanReply(c, pcpbd, msgReply, methodName, false); + if ( msgReply == NULL ) + { + return ReplyFalse; + } + + // Return true to accept the edited text, false to cancel + // it. The return from Rexx is the same. + setWindowPtr(pcpbd->hDlg, DWLP_MSGRESULT, msgReply == TheTrueObj ? TRUE : FALSE); + } + else + { + RexxStringObject mthName = c->String(methodName); + invokeDispatch(c, pcpbd->rexxSelf, mthName, args); + c->ReleaseLocalReference(mthName); + } + + c->ReleaseLocalReference(idFrom); + c->ReleaseLocalReference(itemID); + c->ReleaseLocalReference(rxLV); + if ( text != TheNilObj ) + { + c->ReleaseLocalReference(text); + } + c->ReleaseLocalReference(args); + + return ReplyTrue; + } + case LVN_GETINFOTIP : { NMLVGETINFOTIP *tip = (LPNMLVGETINFOTIP)lParam; @@ -2266,18 +2411,16 @@ * * @return MsgReplyType * - * @remarks Note that most of the tree-view notifications are still handled - * using the old IBM ooDialog code. Currently only the - * TVN_ITEMEXPANDING and TVn_ITEMEXPANDED notifications are tagged - * with TAG_TREEVIEW. + * @remarks Note that some of the tree-view notifications are still handled + * using the old IBM ooDialog code. * * TVN_ITEMEXPANDING: The Rexx programmer returns .true expanding / * collapsing the item is okay, or .false do not allow the expansion / * collapse. * * TVN_ITEMEXPANDED: If the Rexx programmer sets 'willReply' to true, - * we wait for the reply, but discard the actual. This then has the - * 'sync' effect. + * we wait for the reply, but discard the actual reply. This then has + * the 'sync' effect. */ MsgReplyType processTVN(RexxThreadContext *c, CSTRING methodName, uint32_t tag, uint32_t code, LPARAM lParam, pCPlainBaseDialog pcpbd) { @@ -2291,7 +2434,7 @@ case TVN_ITEMEXPANDED : case TVN_ITEMEXPANDING : { - NMTREEVIEW *nmtv = (NM_TREEVIEW *)lParam; + NMTREEVIEW *nmtv = (NMTREEVIEW *)lParam; // The arguements are the same whether we wait for the reply or not. RexxObjectPtr handle = pointer2string(c, nmtv->itemNew.hItem); @@ -2353,6 +2496,165 @@ return ReplyTrue; } + case TVN_BEGINLABELEDIT : + { + NMTVDISPINFO *pdi = (NMTVDISPINFO *)lParam; + + HWND hTv = pdi->hdr.hwndFrom; + HWND hEdit = TreeView_GetEditControl(hTv); + tvSubclassEdit(hTv, hEdit, pdi->hdr.idFrom); + + RexxArrayObject args; + + if ( (tag & TAG_FLAGMASK) == TAG_PRESERVE_OLD ) + { + // To preserve old behaviour for DefTreeEditStarter, all that's + // needed is to set the subclass. Otherwise, we also need to + // invoke the named method with the old args. + if ( toupper(*methodName) == 'B' ) + { + RexxStringObject mthName = c->String(methodName); + RexxObjectPtr hItem = pointer2string(c, pdi->item.hItem); + + args = c->ArrayOfTwo(idFrom, hItem); + invokeDispatch(c, pcpbd->rexxSelf, mthName, args); + + c->ReleaseLocalReference(mthName); + c->ReleaseLocalReference(hItem); + c->ReleaseLocalReference(args); + } + + return ReplyTrue; + } + + RexxObjectPtr hItem = pointer2string(c, pdi->item.hItem); + RexxObjectPtr rxTv = createControlFromHwnd(c, pcpbd, pdi->hdr.hwndFrom, winTreeView, true); + RexxObjectPtr rxEdit = createControlFromHwnd(c, pcpbd, hEdit, winEdit, false); + RexxObjectPtr userData = pdi->item.lParam != NULL ? (RexxObjectPtr)pdi->item.lParam : TheNilObj; + + args = c->ArrayOfFour(idFrom, hItem, rxEdit, rxTv); + c->ArrayAppend(args, userData); + + if ( expectReply ) + { + RexxObjectPtr msgReply = c->SendMessage(pcpbd->rexxSelf, methodName, args); + + msgReply = requiredBooleanReply(c, pcpbd, msgReply, methodName, false); + if ( msgReply == NULL ) + { + return ReplyFalse; + } + + // Return false to let the text be edited, true to disallow it. + // The return from Rexx is true to allow, false to disallow. + setWindowPtr(pcpbd->hDlg, DWLP_MSGRESULT, msgReply == TheTrueObj ? FALSE : TRUE); + } + else + { + RexxStringObject mthName = c->String(methodName); + invokeDispatch(c, pcpbd->rexxSelf, mthName, args); + c->ReleaseLocalReference(mthName); + } + + c->ReleaseLocalReference(idFrom); + c->ReleaseLocalReference(hItem); + if ( rxTv != TheNilObj ) + { + c->ReleaseLocalReference(rxTv); + } + if ( rxEdit != TheNilObj ) + { + c->ReleaseLocalReference(rxEdit); + } + c->ReleaseLocalReference(args); + + return ReplyTrue; + } + + case TVN_ENDLABELEDIT : + { + NMTVDISPINFO *pdi = (NMTVDISPINFO *)lParam; + + RexxArrayObject args; + + if ( (tag & TAG_FLAGMASK) == TAG_PRESERVE_OLD ) + { + // To preserve old behaviour for DefTeeEditHandler, we don't + // need to do anything. Otherwise, we need to invoke the named + // method with the old args. + if ( toupper(*methodName) == 'B' ) + { + RexxStringObject mthName = c->String(methodName); + RexxObjectPtr hItem = pointer2string(c, pdi->item.hItem); + RexxObjectPtr text = pdi->item.pszText ? c->String(pdi->item.pszText) : NULLOBJECT; + + if ( text != NULLOBJECT ) + { + args = c->ArrayOfThree(idFrom, hItem, text); + invokeDispatch(c, pcpbd->rexxSelf, mthName, args); + + c->ReleaseLocalReference(text); + } + else + { + args = c->ArrayOfTwo(idFrom, hItem); + invokeDispatch(c, pcpbd->rexxSelf, mthName, args); + } + + c->ReleaseLocalReference(mthName); + c->ReleaseLocalReference(idFrom); + c->ReleaseLocalReference(hItem); + c->ReleaseLocalReference(args); + } + + setWindowPtr(pcpbd->hDlg, DWLP_MSGRESULT, pdi->item.pszText ? TRUE : FALSE); + return ReplyTrue; + } + + RexxObjectPtr hItem = pointer2string(c, pdi->item.hItem); + RexxObjectPtr text = pdi->item.pszText ? c->String(pdi->item.pszText) : TheNilObj; + RexxObjectPtr rxTv = createControlFromHwnd(c, pcpbd, pdi->hdr.hwndFrom, winTreeView, true); + RexxObjectPtr userData = pdi->item.lParam != NULL ? (RexxObjectPtr)pdi->item.lParam : TheNilObj; + + args = c->ArrayOfFour(idFrom, hItem, text, rxTv); + c->ArrayAppend(args, userData); + + if ( expectReply ) + { + RexxObjectPtr msgReply = c->SendMessage(pcpbd->rexxSelf, methodName, args); + + msgReply = requiredBooleanReply(c, pcpbd, msgReply, methodName, false); + if ( msgReply == NULL ) + { + return ReplyFalse; + } + + // Return true to accept the edited text, false to cancel + // it. The return from Rexx is the same. + setWindowPtr(pcpbd->hDlg, DWLP_MSGRESULT, msgReply == TheTrueObj ? TRUE : FALSE); + } + else + { + RexxStringObject mthName = c->String(methodName); + invokeDispatch(c, pcpbd->rexxSelf, mthName, args); + c->ReleaseLocalReference(mthName); + } + + c->ReleaseLocalReference(idFrom); + c->ReleaseLocalReference(hItem); + if ( text != TheNilObj ) + { + c->ReleaseLocalReference(text); + } + if ( rxTv != TheNilObj ) + { + c->ReleaseLocalReference(rxTv); + } + c->ReleaseLocalReference(args); + + return ReplyTrue; + } + case TVN_GETINFOTIP : { NMTVGETINFOTIP *tip = (LPNMTVGETINFOTIP)lParam; @@ -2729,19 +3031,8 @@ break; } - /* do we have an end label edit for tree or list view? */ - if ( (code == TVN_ENDLABELEDIT) && ((TV_DISPINFO *)lParam)->item.pszText ) - { - np = ((TV_DISPINFO *)lParam)->item.pszText; - handle = ((TV_DISPINFO *)lParam)->item.hItem; - } - else if ( (code == LVN_ENDLABELEDIT) && ((LV_DISPINFO *)lParam)->item.pszText ) - { - np = ((LV_DISPINFO *)lParam)->item.pszText; - item = ((LV_DISPINFO *)lParam)->item.iItem; - } /* do we have a key_down? */ - else if ( (code == TVN_KEYDOWN) || (code == LVN_KEYDOWN) || (code == TCN_KEYDOWN) ) + if ( (code == TVN_KEYDOWN) || (code == LVN_KEYDOWN) || (code == TCN_KEYDOWN) ) { lParam = (ULONG)((TV_KEYDOWN *)lParam)->wVKey; } @@ -3463,10 +3754,22 @@ else if ( StrCmpI(keyword, "BEGINDRAG" ) == 0 ) tvn = TVN_BEGINDRAG; else if ( StrCmpI(keyword, "BEGINRDRAG" ) == 0 ) tvn = TVN_BEGINRDRAG; else if ( StrCmpI(keyword, "DELETE" ) == 0 ) tvn = TVN_DELETEITEM; - else if ( StrCmpI(keyword, "BEGINEDIT" ) == 0 ) tvn = TVN_BEGINLABELEDIT; - else if ( StrCmpI(keyword, "ENDEDIT" ) == 0 ) tvn = TVN_ENDLABELEDIT; else if ( StrCmpI(keyword, "KEYDOWN" ) == 0 ) tvn = TVN_KEYDOWN; - else if ( StrCmpI(keyword, "DEFAULTEDIT") == 0 ) *isDefEdit = true; + else if ( StrCmpI(keyword, "BEGINEDIT" ) == 0 ) + { + tvn = TVN_BEGINLABELEDIT; + *tag = TAG_TREEVIEW; + } + else if ( StrCmpI(keyword, "ENDEDIT" ) == 0 ) + { + tvn = TVN_ENDLABELEDIT; + *tag = TAG_TREEVIEW; + } + else if ( StrCmpI(keyword, "DEFAULTEDIT") == 0 ) + { + *isDefEdit = true; + *tag = TAG_TREEVIEW | TAG_PRESERVE_OLD; + } else if ( StrCmpI(keyword, "EXPANDING" ) == 0 ) { tvn = TVN_ITEMEXPANDING; @@ -3551,13 +3854,25 @@ else if ( StrCmpI(keyword, "INSERTED") == 0 ) lvn = LVN_INSERTITEM; else if ( StrCmpI(keyword, "DELETE") == 0 ) lvn = LVN_DELETEITEM; else if ( StrCmpI(keyword, "DELETEALL") == 0 ) lvn = LVN_DELETEALLITEMS; - else if ( StrCmpI(keyword, "BEGINEDIT") == 0 ) lvn = LVN_BEGINLABELEDIT; - else if ( StrCmpI(keyword, "ENDEDIT") == 0 ) lvn = LVN_ENDLABELEDIT; else if ( StrCmpI(keyword, "BEGINDRAG") == 0 ) lvn = LVN_BEGINDRAG; else if ( StrCmpI(keyword, "BEGINRDRAG") == 0 ) lvn = LVN_BEGINRDRAG; else if ( StrCmpI(keyword, "ACTIVATE") == 0 ) lvn = LVN_ITEMACTIVATE; else if ( StrCmpI(keyword, "KEYDOWN") == 0 ) lvn = LVN_KEYDOWN; - else if ( StrCmpI(keyword, "DEFAULTEDIT") == 0 ) *isDefEdit = true; + else if ( StrCmpI(keyword, "DEFAULTEDIT") == 0 ) + { + *isDefEdit = true; + *tag = TAG_LISTVIEW | TAG_PRESERVE_OLD; + } + else if ( StrCmpI(keyword, "BEGINEDIT") == 0 ) + { + lvn = LVN_BEGINLABELEDIT; + *tag = TAG_LISTVIEW; + } + else if ( StrCmpI(keyword, "ENDEDIT") == 0 ) + { + lvn = LVN_ENDLABELEDIT; + *tag = TAG_LISTVIEW; + } else if ( StrCmpI(keyword, "CLICK") == 0 ) { lvn = NM_CLICK; @@ -5415,6 +5730,41 @@ * backwards compatibility. Essentially, for this method, all * behaviour needs to be pre-4.2.0. The only change is that for * tagged list view events, the user can specify to reply directly. + * + * The processing for beginlabeledit and endlabeledit that was done + * for the DEFAULTEDIT keyword is not needed for a list-view. + * defListEditStarter and defListEditHandler methods are not needed + * and the methods are removed from the list-view. For backwards + * compatibility, if the keyword DEFAULTEDIT, we only connect the + * defListEditHandler. We need that to catch the message. A tag is + * added for preserve old behavior and within processLVN() we simply + * do what the old defListEditHandler did. Set the label text if + * the user did not cancel, don't set the label if the user did + * cancel. + * + * For reference. The arguments sent to the event handler for + * LVN_ENDLABELEDIT were never documented correctly, if at all. + * They were as follows. If the user did *not* cancel the edit: + * arg 1 list-view id (from wParam) + * arg 2 item being edited id (0 based) + * arg 3 text user entered. + * + * If the user did cancel the edit: + * arg 1 list-view id (from wParam) + * arg 2 pointer to the NMLVDISPINFO struct as a decimal value + * (from lParam) + * + * Note: it is highly unlikely that anyone ever connected + * LVN_ENDLABELEDIT in the old ooDialog, but if they did, the + * willReply argument would be omitted. We do a special check for + * this and preserve what would have been the old behaviour. That + * is: use invoke dispatch and use the arguments listed above. + * + * The arguments to the event handler for LVN_BEGINLABELEDIT were + * never documented at all. For reference they were: + * arg 1 list-view id (from wParam) + * arg 2 pointer to the NMLVDISPINFO struct as a decimal value + * (from lParam) */ RexxMethod5(RexxObjectPtr, en_connectListViewEvent, RexxObjectPtr, rxID, CSTRING, event, OPTIONAL_CSTRING, methodName, OPTIONAL_logical_t, willReply, CSELF, pCSelf) @@ -5436,17 +5786,14 @@ return TheNegativeOneObj; } - // Deal with DEFAULTEDIT separately. + // Deal with DEFAULTEDIT separately. For LVN_BEGINLABELEDIT, we do not need + // to handle the event if ( isDefEdit ) { - if ( ! addNotifyMessage(pcen, context, id, 0xFFFFFFFF, LVN_BEGINLABELEDIT, 0xFFFFFFFF, "DefListEditStarter", 0) ) + if ( ! addNotifyMessage(pcen, context, id, 0xFFFFFFFF, LVN_ENDLABELEDIT, 0xFFFFFFFF, "DefListEditHandler", tag) ) { return TheNegativeOneObj; } - if ( ! addNotifyMessage(pcen, context, id, 0xFFFFFFFF, LVN_ENDLABELEDIT, 0xFFFFFFFF, "DefListEditHandler", 0) ) - { - return TheNegativeOneObj; - } return TheZeroObj; } @@ -5455,6 +5802,11 @@ methodName = lvn2name(notificationCode, tag); } + if ( (notificationCode == LVN_BEGINLABELEDIT || notificationCode == LVN_ENDLABELEDIT) && argumentOmitted(4) ) + { + tag |= TAG_PRESERVE_OLD; + } + if ( addNotifyMessage(pcen, context, id, 0xFFFFFFFF, notificationCode, 0xFFFFFFFF, methodName, tag) ) { return TheZeroObj; @@ -5705,8 +6057,36 @@ * * EXPANDING / EXPANDED The willReply request is honored * + * BEGINLABELEDIT / ENDLABELEDIT + * * INFOTIP new keyword - will reply is always set to true for this * keyword. + * + * The processing for beginlabeledit and endlabeledit that was done + * for the DEFAULTEDIT keyword is not all needed for a tree-view. + * This is changed in a similar manner as the list-view was changed. + * However, for a tree-view if we do not subclass the edit control, + * the enter and the esc key close the dialog. What we do here is + * very similar to what we do in the connect list-view event + * function. See that header doc if more detail is neede. + * + * For reference. The arguments sent to the event handler for + * TVN_ENDLABELEDIT were never documented correctly, if at all. + * They were as follows. If the user did *not* cancel the edit: + * arg 1 tree-view id (from wParam) + * arg 2 handle of item being edited + * arg 3 text user entered. + * + * If the user did cancel the edit: + * arg 1 tree-view id (from wParam) + * arg 2 pointer to the NMLVDISPINFO struct as a decimal value + * (from lParam) + * + * The arguments to the event handler for TVN_BEGINLABELEDIT were + * never documented at all. For reference they were: + * arg 1 tree-view id (from wParam) + * arg 2 pointer to the NMLVDISPINFO struct as a decimal value + * (from lParam) */ RexxMethod5(RexxObjectPtr, en_connectTreeViewEvent, RexxObjectPtr, rxID, CSTRING, event, OPTIONAL_CSTRING, methodName, OPTIONAL_logical_t, willReply, CSELF, pCSelf) @@ -5731,11 +6111,11 @@ // Deal with DEFAULTEDIT separately. if ( isDefEdit ) { - if ( ! addNotifyMessage(pcen, context, id, 0xFFFFFFFF, TVN_BEGINLABELEDIT, 0xFFFFFFFF, "DefTreeEditStarter", 0) ) + if ( ! addNotifyMessage(pcen, context, id, 0xFFFFFFFF, TVN_BEGINLABELEDIT, 0xFFFFFFFF, "DefTreeEditStarter", tag) ) { return TheNegativeOneObj; } - if ( ! addNotifyMessage(pcen, context, id, 0xFFFFFFFF, TVN_ENDLABELEDIT, 0xFFFFFFFF, "DefTreeEditHandler", 0) ) + if ( ! addNotifyMessage(pcen, context, id, 0xFFFFFFFF, TVN_ENDLABELEDIT, 0xFFFFFFFF, "DefTreeEditHandler", tag) ) { return TheNegativeOneObj; } @@ -5747,6 +6127,11 @@ methodName = tvn2name(notificationCode, tag); } + if ( notificationCode == TVN_ENDLABELEDIT && argumentOmitted(4) ) + { + tag |= TAG_PRESERVE_OLD; + } + if ( addNotifyMessage(pcen, context, id, 0xFFFFFFFF, notificationCode, 0xFFFFFFFF, methodName, tag) ) { return TheZeroObj; Modified: ooDialog/trunk/ooDialog/oodPackageEntry.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-11-03 19:17:06 UTC (rev 8555) @@ -612,8 +612,6 @@ REXX_METHOD_PROTOTYPE(pbdlg_dumpMessageTable); REXX_METHOD_PROTOTYPE(pbdlg_unInit); -REXX_METHOD_PROTOTYPE(generic_setListTabulators); -REXX_METHOD_PROTOTYPE(generic_subclassEdit); REXX_METHOD_PROTOTYPE(global_resolveSymbolicID); // DialogExtensions @@ -899,6 +897,12 @@ REXX_METHOD_PROTOTYPE(dlgctrl_textSize); REXX_METHOD_PROTOTYPE(dlgctrl_putInBag); +// Generic methods for dialog controls +REXX_METHOD_PROTOTYPE(generic_getToolTips); +REXX_METHOD_PROTOTYPE(generic_setListTabulators); +REXX_METHOD_PROTOTYPE(generic_subclassEdit); +REXX_METHOD_PROTOTYPE(generic_setToolTips); + // Static REXX_METHOD_PROTOTYPE(stc_getIcon); REXX_METHOD_PROTOTYPE(stc_setIcon); @@ -1107,15 +1111,19 @@ REXX_METHOD_PROTOTYPE(tt_addToolRect); REXX_METHOD_PROTOTYPE(tt_adjustRect); REXX_METHOD_PROTOTYPE(tt_delTool); +REXX_METHOD_PROTOTYPE(tt_enumTools); REXX_METHOD_PROTOTYPE(tt_getCurrentToolInfo); +REXX_METHOD_PROTOTYPE(tt_getToolCount); REXX_METHOD_PROTOTYPE(tt_getToolInfo); REXX_METHOD_PROTOTYPE(tt_popUp); REXX_METHOD_PROTOTYPE(tt_setMaxTipWidth); REXX_METHOD_PROTOTYPE(tt_trackActivate); REXX_METHOD_PROTOTYPE(tt_trackPosition); +REXX_METHOD_PROTOTYPE(tt_useRelayEvent); // ToolInfo REXX_METHOD_PROTOTYPE(ti_fromID_cls); +REXX_METHOD_PROTOTYPE(ti_fromIdEx_cls); REXX_METHOD_PROTOTYPE(ti_init); REXX_METHOD_PROTOTYPE(ti_unInit); REXX_METHOD_PROTOTYPE(ti_flags); @@ -1612,8 +1620,6 @@ REXX_METHOD(pbdlg_dumpMessageTable, pbdlg_dumpMessageTable), REXX_METHOD(pbdlg_unInit, pbdlg_unInit), - REXX_METHOD(generic_setListTabulators, generic_setListTabulators), - REXX_METHOD(generic_subclassEdit, generic_subclassEdit), REXX_METHOD(global_resolveSymbolicID, global_resolveSymbolicID), REXX_METHOD(dlgext_setWindowRect, dlgext_setWindowRect), @@ -1683,27 +1689,6 @@ REXX_METHOD(dyndlg_startChildDialog, dyndlg_startChildDialog), REXX_METHOD(dyndlg_stop, dyndlg_stop), - REXX_METHOD(dlgctrl_new_cls, dlgctrl_new_cls), - REXX_METHOD(dlgctrl_init_cls, dlgctrl_init_cls), - REXX_METHOD(dlgctrl_init, dlgctrl_init), - REXX_METHOD(dlgctrl_unInit, dlgctrl_unInit), - REXX_METHOD(dlgctrl_addUserSubclass, dlgctrl_addUserSubclass), - REXX_METHOD(dlgctrl_assignFocus, dlgctrl_assignFocus), - REXX_METHOD(dlgctrl_clearRect, dlgctrl_clearRect), - REXX_METHOD(dlgctrl_connectEvent, dlgctrl_connectEvent), - REXX_METHOD(dlgctrl_connectFKeyPress, dlgctrl_connectFKeyPress), - REXX_METHOD(dlgctrl_connectKeyPress, dlgctrl_connectKeyPress), - REXX_METHOD(dlgctrl_data, dlgctrl_data), - REXX_METHOD(dlgctrl_dataEquals, dlgctrl_dataEquals), - REXX_METHOD(dlgctrl_disconnectKeyPress, dlgctrl_disconnectKeyPress), - REXX_METHOD(dlgctrl_getTextSizeDlg, dlgctrl_getTextSizeDlg), - REXX_METHOD(dlgctrl_hasKeyPressConnection, dlgctrl_hasKeyPressConnection), - REXX_METHOD(dlgctrl_redrawRect, dlgctrl_redrawRect), - REXX_METHOD(dlgctrl_setColor, dlgctrl_setColor), - REXX_METHOD(dlgctrl_tabGroup, dlgctrl_tabGroup), - REXX_METHOD(dlgctrl_textSize, dlgctrl_textSize), - REXX_METHOD(dlgctrl_putInBag, dlgctrl_putInBag), - REXX_METHOD(window_init, window_init), REXX_METHOD(window_unInit, window_unInit), @@ -1855,6 +1840,7 @@ REXX_METHOD(winex_textBkMode, winex_textBkMode), REXX_METHOD(winex_getSetArcDirection, winex_getSetArcDirection), + // ResourceImage REXX_METHOD(ri_init, ri_init), REXX_METHOD(ri_release, ri_release), REXX_METHOD(ri_handle, ri_handle), @@ -1863,6 +1849,7 @@ REXX_METHOD(ri_getImage, ri_getImage), REXX_METHOD(ri_getImages, ri_getImages), + // Image REXX_METHOD(image_toID_cls, image_toID_cls), REXX_METHOD(image_getImage_cls, image_getImage_cls), REXX_METHOD(image_fromFiles_cls, image_fromFiles_cls), @@ -1878,6 +1865,7 @@ REXX_METHOD(image_systemErrorCode, image_systemErrorCode), REXX_METHOD(image_handle, image_handle), + // ImageList REXX_METHOD(il_create_cls, il_create_cls), REXX_METHOD(il_init, il_init), REXX_METHOD(il_release, il_release), @@ -1893,6 +1881,33 @@ REXX_METHOD(il_isNull, il_isNull), REXX_METHOD(il_handle, il_handle), + // DialogControl + REXX_METHOD(dlgctrl_new_cls, dlgctrl_new_cls), + REXX_METHOD(dlgctrl_init_cls, dlgctrl_init_cls), + REXX_METHOD(dlgctrl_init, dlgctrl_init), + REXX_METHOD(dlgctrl_unInit, dlgctrl_unInit), + REXX_METHOD(dlgctrl_addUserSubclass, dlgctrl_addUserSubclass), + REXX_METHOD(dlgctrl_assignFocus, dlgctrl_assignFocus), + REXX_METHOD(dlgctrl_clearRect, dlgctrl_clearRect), + REXX_METHOD(dlgctrl_connectEvent, dlgctrl_connectEvent), + REXX_METHOD(dlgctrl_connectFKeyPress, dlgctrl_connectFKeyPress), + REXX_METHOD(dlgctrl_connectKeyPress, dlgctrl_connectKeyPress), + REXX_METHOD(dlgctrl_data, dlgctrl_data), + REXX_METHOD(dlgctrl_dataEquals, dlgctrl_dataEquals), + REXX_METHOD(dlgctrl_disconnectKeyPress, dlgctrl_disconnectKeyPress), + REXX_METHOD(dlgctrl_getTextSizeDlg, dlgctrl_getTextSizeDlg), + REXX_METHOD(dlgctrl_hasKeyPressConnection, dlgctrl_hasKeyPressConnection), + REXX_METHOD(dlgctrl_redrawRect, dlgctrl_redrawRect), + REXX_METHOD(dlgctrl_setColor, dlgctrl_setColor), + REXX_METHOD(dlgctrl_tabGroup, dlgctrl_tabGroup), + REXX_METHOD(dlgctrl_textSize, dlgctrl_textSize), + REXX_METHOD(dlgctrl_putInBag, dlgctrl_putInBag), + + // Generic methods for dialog control + REXX_METHOD(generic_getToolTips, generic_getToolTips), + REXX_METHOD(generic_setListTabulators, generic_setListTabulators), + REXX_METHOD(generic_setToolTips, generic_setToolTips), + // Static REXX_METHOD(stc_getIcon, stc_getIcon), REXX_METHOD(stc_setIcon, stc_setIcon), @@ -2076,15 +2091,19 @@ REXX_METHOD(tt_addToolRect, tt_addToolRect), REXX_METHOD(tt_adjustRect, tt_adjustRect), REXX_METHOD(tt_delTool, tt_delTool), + REXX_METHOD(tt_enumTools, tt_enumTools), REXX_METHOD(tt_getCurrentToolInfo, tt_getCurrentToolInfo), + REXX_METHOD(tt_getToolCount, tt_getToolCount), REXX_METHOD(tt_getToolInfo, tt_getToolInfo), REXX_METHOD(tt_popUp, tt_popUp), REXX_METHOD(tt_setMaxTipWidth, tt_setMaxTipWidth), REXX_METHOD(tt_trackActivate, tt_trackActivate), REXX_METHOD(tt_trackPosition, tt_trackPosition), + REXX_METHOD(tt_useRelayEvent, tt_useRelayEvent), // ToolInfo REXX_METHOD(ti_fromID_cls, ti_fromID_cls), + REXX_METHOD(ti_fromIdEx_cls, ti_fromIdEx_cls), REXX_METHOD(ti_init, ti_init), REXX_METHOD(ti_unInit, ti_unInit), REXX_METHOD(ti_flags, ti_flags), Modified: ooDialog/trunk/ooDialog/oodToolTip.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodToolTip.cpp 2012-11-02 14:50:15 UTC (rev 8554) +++ ooDialog/trunk/ooDialog/oodToolTip.cpp 2012-11-03 19:17:06 UTC (rev 8555) @@ -43,6 +43,7 @@ #include "ooDialog.hpp" // Must be first, includes windows.h, commctrl.h, and oorexxapi.h #include <shlwapi.h> +#include <WindowsX.h> #include "APICommon.hpp" #include "oodCommon.hpp" @@ -94,6 +95,30 @@ return c->String(buf); } +/** + * Convert a mouse window message code to a name. + */ +inline RexxStringObject mousemsg2name(RexxThreadContext *c, uint32_t msg) +{ + switch ( msg ) + { + case WM_MOUSEMOVE : return c->String("mouseMove "); + case WM_LBUTTONDOWN : return c->String("lButtonDown "); + case WM_LBUTTONUP : return c->String("lButtonUp "); + case WM_LBUTTONDBLCLK : return c->String("lButtonDblClk"); + case WM_RBUTTONDOWN : return c->String("rButtonDown "); + case WM_RBUTTONUP : return c->String("rButtonUp "); + case WM_RBUTTONDBLCLK : return c->String("rButtonDblClk"); + case WM_MBUTTONDOWN : return c->String("mButtonDown "); + case WM_MBUTTONUP : return c->String("mButtonUp "); + case WM_MBUTTONDBLCLK : return c->String("mButtonDblClk"); + case WM_XBUTTONDOWN : return c->String("xButtonDown "); + case WM_XBUTTONUP : return c->String("xButtonUp "); + case WM_XBUTTONDBLCLK : return c->String("xButtonDblClk"); + case WM_MOUSEWHEEL : return c->String("mouseWheel "); + } + return c->String("unknown"); +} /** * Methods for the .ToolTip class. @@ -379,7 +404,111 @@ return rxID; } +inline void freeRelayData(pRelayEventData pData) +{ + safeLocalFree(pData->method); + safeLocalFree(pData); +} +LRESULT CALLBACK RelayEventSubclassProc(HWND hwnd, uint32_t msg, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR dwData) +{ + pRelayEventData pData = (pRelayEventData)dwData; + + ///* + if ( (msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST) || msg == WM_NCMOUSEMOVE) + { + RexxThreadContext *c = pData->pcpbd->dlgProcContext; + + RexxObjectPtr rxPoint = rxNewPoint(c, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + RexxObjectPtr rxMsg = mousemsg2name(c, msg); + + RexxArrayObject args = c->ArrayOfThree(pData->rxToolTip, rxPoint, rxMsg); + + RexxObjectPtr reply = c->SendMessage(pData->pcpbd->rexxSelf, pData->method, args); + + MSG _msg; + _msg.hwnd = hwnd; + _msg.message = msg; + _msg.wParam = wParam; + _msg.lParam = lParam; + _msg.pt.x = GET_X_LPARAM(lParam); + _msg.pt.y = GET_Y_LPARAM(lParam); + SendMessage(pData->hToolTip, TTM_RELAYEVENT, 0, (LPARAM)&_msg); + } + //*/ + + if ( msg == WM_NOTIFY ) + { + uint32_t code = ((NMHDR *)lParam)->code; + if ( code <= TTN_FIRST && code >= TTN_LAST ) + { + printf("Got TTN msg code=%d GDIW=%d Show=%d, Pop=%d GDIA=%d GDI=%d\n", + code, TTN_GETDISPINFOW, TTN_SHOW, TTN_POP, TTN_GETDISPINFOA, TTN_GETDISPINFO); + } + + switch ( code ) + { + case TTN_SHOW : + { + LPARAM lp = DefSubclassProc(hwnd, msg, wParam, lParam); + + HWND hwndToolTip = ((NMHDR *)lParam)->hwndFrom; + + RECT rc; + GetWindowRect(hwndToolTip, &rc); + printf("Current rect left=%d top=%d old lParam=%d hwndToolTip=%p\n", rc.left, rc.top, lp, hwndToolTip); + + rc.left -= 35; + rc.top -= 35; + SetWindowPos(hwndToolTip, + NULL, + rc.left, rc.top, + 0, 0, + SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); + + } return TRUE; + + case TTN_GETDISPINFOW : + { + LPNMTTDISPINFO nmtdi = (LPNMTTDISPINFO)lParam; + printf("GetDispInfo szText=%s lpszText=%s\n", + nmtdi->szText ? nmtdi->szText : "null", + nmtdi->lpszText ? nmtdi->lpszText : "null"); + //nmtdi->lpszText = (LPSTR)ansi2unicode("Test of me"); + //nmtdi->lpszText = (LPSTR)L"Test of me"; + //putUnicodeText((LPWORD)nmtdi->szText, "Test of me"); + strcpy(nmtdi->szText, "Test of me"); + } return TRUE; + + default : + break; + + } + /* + printf("Got WM_NOTIFY code=%d TTNSHOW=%x DispInfoW=%d\n", code, TTN_SHOW, TTN_GETDISPINFOW); + if ( code == TTN_SHOW ) + { + printf("Got WM_NOTIFY and TTN_SHOW\n"); + } + */ + + } + if ( msg == WM_NCDESTROY ) + { + /* The window is being destroyed, remove the subclass, clean up memory. + * Note that with the current ooDialog architecture, this message never + * gets here. Freeing the subclass data struct has to be done in the + * dialog control uninit(). TODO FIX THIS, we never free the data + * struct. + */ + RemoveWindowSubclass(hwnd, RelayEventSubclassProc, pData->id); + freeRelayData(pData); + } + + return DefSubclassProc(hwnd, msg, wParam, lParam); +} + + /** PlainBaseDialog::newToolTip() * * Creates the Windows tool tip control and instantiates the Rexx ToolTip @@ -458,6 +587,8 @@ hToolTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, style, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hDlg, NULL, pcpbd->hInstance, NULL); ctt.errRC = GetLastError(); + + SetWindowPos(hToolTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } else { @@ -859,6 +990,64 @@ } +/** ToolTip::enumTools() + * + * + */ +RexxMethod2(RexxObjectPtr, tt_enumTools, OPTIONAL_uint32_t, index, CSELF, pCSelf) +{ + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) + { + return TheNilObj; + } + + if ( argumentExists(1) ) + { + if ( index < 1 ) + { + wrongRangeException(context, 1, 1, UINT32_MAX, index); + return TheNilObj; + } + index--; + } + else + { + index = 1; + } + + TOOLINFO ti = {sizeof(ti)}; + ti.lpszText = (char *)LocalAlloc(LPTR, 81); + + if ( SendMessage(pcdc->hCtrl, TTM_ENUMTOOLS, index, (LPARAM)&ti) ) + { + printf("Got enum tools tool info text=%p flags =0x%x hwnd=%p uID=%p\n", ti.lpszText, ti.uFlags, ti.hwnd, ti.uId); + } + else + { + printf("Did NOT get enum tools tool info\n"); + } + + return TheNilObj; +} + + +/** ToolTip::getToolCount() + * + * + */ +RexxMethod1(uint32_t, tt_getToolCount, CSELF, pCSelf) +{ + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) + { + return FALSE; + } + + return (uint32_t)SendMessage(pcdc->hCtrl, TTM_GETTOOLCOUNT, 0, 0); +} + + /** ToolTip::getToolInfo() * * @@ -991,7 +1180,82 @@ } +RexxMethod3(logical_t, tt_useRelayEvent, RexxObjectPtr, toolObject, OPTIONAL_CSTRING, method, CSELF, pCSelf) +{ + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) + { + return FALSE; + } + pCDialogControl subClassCtrl = NULL; + + RexxMethodContext *c = context; + if ( context->IsOfType(toolObject, "PLAINBASEDIALOG") ) + { + userDefinedMsgException(context->threadContext, 1, "useRelayEvent() is not implemented for dialogs yet"); + return FALSE; + } + else if ( context->IsOfType(toolObject, "DIALOGCONTROL") ) + { + subClassCtrl = controlToCSelf(context, toolObject); + } + else + { + wrongClassListException(context->threadContext, 1, "PlainBaseDialog or DialogControl", toolObject); + return FALSE; + } + + if ( argumentOmitted(2) ) + { + method = "onMouseRelayEvent"; + } + + pRelayEventData pSCData = (pRelayEventData)LocalAlloc(LPTR, sizeof(RelayEventData)... [truncated message content] |
From: <mie...@us...> - 2012-11-04 16:40:25
|
Revision: 8557 http://sourceforge.net/p/oorexx/code-0/8557 Author: miesfeld Date: 2012-11-04 16:40:23 +0000 (Sun, 04 Nov 2012) Log Message: ----------- ooDialog - update the oodListViews example to use some of the new ListView features. Modified Paths: -------------- ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.h ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.rc ooDialog/trunk/ooDialog/oodMessaging.cpp Modified: ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex =================================================================== --- ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex 2012-11-04 05:09:22 UTC (rev 8556) +++ ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex 2012-11-04 16:40:23 UTC (rev 8557) @@ -46,7 +46,7 @@ * Demonstrates the different views possible in the list-view control. Shows * how to use the ControlDialog class to populate each page in a tab * control. Demonstrates some other list-view features, such as info tips, - * etc.. + * user item data, in place label editing, drag and drop in icon view, etc.. * */ @@ -86,9 +86,10 @@ self~createImageLists self~initRecords - self~connectButtonEvent(IDC_PB_ADDRECORD, "CLICKED", "onAdd") - self~connectButtonEvent(IDC_PB_FORWARD, "CLICKED", "onForward") - self~connectButtonEvent(IDC_PB_BACKWARD, "CLICKED", "onBackward") + self~connectButtonEvent(IDC_PB_ADDRECORD, "CLICKED", "onAdd") + self~connectButtonEvent(IDC_PB_EDITRECORD, "CLICKED", "onEdit") + self~connectButtonEvent(IDC_PB_FORWARD, "CLICKED", "onForward") + self~connectButtonEvent(IDC_PB_BACKWARD, "CLICKED", "onBackward") self~connectButtonEvent(IDC_CK_INFOTIPS, "CLICKED", onCheckClicked) @@ -102,6 +103,9 @@ ckInfoTips = self~newCheckBox(IDC_CK_INFOTIPS) ckInfoTips~check + -- Disable the edit record push button. + self~newPushButton(IDC_PB_EDITRECORD)~disable + -- Save a reference to the push buttons. pbBackward = self~newPushButton(IDC_PB_BACKWARD) pbForward = self~newPushButton(IDC_PB_Forward) @@ -282,14 +286,16 @@ if dlg~initCode = 0 then do if dlg~execute("SHOWTOP") == self~IDOK then do + rec = .directory~new - rec~FirstName = dlg~IDC_EDIT_FNAME - rec~Lastname = dlg~IDC_EDIT_LNAME - rec~Street = dlg~IDC_EDIT_STREET - rec~City = dlg~IDC_EDIT_CITY - rec~State = dlg~IDC_EDIT_STATE - rec~ZipCode = dlg~IDC_EDIT_ZIPCODE - rec~Age = dlg~IDC_EDIT_AGE + rec~FirstName = dlg~IDC_EDIT_FNAME + rec~Lastname = dlg~IDC_EDIT_LNAME + rec~Street = dlg~IDC_EDIT_STREET + rec~City = dlg~IDC_EDIT_CITY + rec~State = dlg~IDC_EDIT_STATE + rec~ZipCode = dlg~IDC_EDIT_ZIPCODE + rec~Age = dlg~IDC_EDIT_AGE + rec~isEditable = dlg~IDC_CHK_EDITABLE if dlg~IDC_RB_MALE = 1 then rec~Sex = "M" else rec~Sex = "F" @@ -300,6 +306,44 @@ end +/** onEdit() + * + * The event handle for the 'Edit' button's CLICKED event. Here we display the + * address dialog, but set its mode to edit, which allows the user to edit an + * existing record. + * + * The address dialog is set in edit mode by passing a record into init(). If + * the address dialog is ended with okay, then we update the record with the + * values the user entered and have the page dialog update the list-view item. + */ +::method onEdit unguarded + expose pageDialog + + rec = pageDialog~getSelectedRecord + + dlg = .AddressDialog~new('rc\oodListViews.rc', IDD_ADDRESS, rec) + + if dlg~initCode = 0 then do + if dlg~execute("SHOWTOP") == self~IDOK then do + + rec~FirstName = dlg~IDC_EDIT_FNAME + rec~Lastname = dlg~IDC_EDIT_LNAME + rec~Street = dlg~IDC_EDIT_STREET + rec~City = dlg~IDC_EDIT_CITY + rec~State = dlg~IDC_EDIT_STATE + rec~ZipCode = dlg~IDC_EDIT_ZIPCODE + rec~Age = dlg~IDC_EDIT_AGE + rec~isEditable = dlg~IDC_CHK_EDITABLE + + if dlg~IDC_RB_MALE = 1 then rec~Sex = "M" + else rec~Sex = "F" + + -- Have the page dialog refresh, update, the item. + pageDialog~refreshSelectedItem + end + end + + /** cancel() * * The user can not end a ControlDialog, so we need to end the page dialog @@ -412,36 +456,39 @@ records = .array~new(3) rec = .directory~new - rec~FirstName = "Mike" - rec~Lastname = "Miller" - rec~Street = "432 Fifth Ave" - rec~City = "New York" - rec~State = "NY" - rec~ZipCode = "12897" - rec~Age = "35" - rec~Sex = "M" + rec~FirstName = "Mike" + rec~Lastname = "Miller" + rec~Street = "432 Fifth Ave" + rec~City = "New York" + rec~State = "NY" + rec~ZipCode = "12897" + rec~Age = "35" + rec~Sex = "M" + rec~IsEditable = .false records[1] = rec rec = .directory~new - rec~FirstName = "Sue" - rec~Lastname = "Thaxton" - rec~Street = "5179 Bellevue St" - rec~City = "Tucson" - rec~State = "AZ" - rec~ZipCode = "87340" - rec~Age = "30" - rec~Sex = "F" + rec~FirstName = "Sue" + rec~Lastname = "Thaxton" + rec~Street = "5179 Bellevue St" + rec~City = "Tucson" + rec~State = "AZ" + rec~ZipCode = "87340" + rec~Age = "30" + rec~Sex = "F" + rec~IsEditable = .true records[2] = rec rec = .directory~new - rec~FirstName = "Dave" - rec~Lastname = "Hewitt" - rec~Street = "4932 Texas St" - rec~City = "San Diego" - rec~State = "CA" - rec~ZipCode = "92110" - rec~Age = "49" - rec~Sex = "M" + rec~FirstName = "Dave" + rec~Lastname = "Hewitt" + rec~Street = "4932 Texas St" + rec~City = "San Diego" + rec~State = "CA" + rec~ZipCode = "92110" + rec~Age = "49" + rec~Sex = "M" + rec~IsEditable = .true records[3] = rec @@ -457,17 +504,22 @@ ::attribute useInfoTips ::method initialize - expose smallIcons normalIcons records + expose smallIcons normalIcons records haveSelection pbEdit use strict arg smallIcons, normalIcons, records self~connectListViewEvent(IDC_LISTVIEW, "COLUMNCLICK") self~connectListViewEvent(IDC_LISTVIEW, "ACTIVATE", "onDoubleClick") self~connectListViewEvent(IDC_LISTVIEW, "BEGINDRAG", "DefListDragHandler") - self~connectListViewEvent(IDC_LISTVIEW, "DEFAULTEDIT") + self~connectListViewEvent(IDC_LISTVIEW, "BEGINEDIT", "onBeginEdit", .true) + self~connectListViewEvent(IDC_LISTVIEW, "ENDEDIT", , .true) self~connectListViewEvent(IDC_LISTVIEW, "GETINFOTIP") + self~connectListViewEvent(IDC_LISTVIEW, "SELECTCHANGED") self~initUpdateListView(IDC_LISTVIEW) + haveSelection = .false + pbEdit = self~ownerDialog~newPushButton(IDC_PB_EDITRECORD) + ::method initDialog expose lv smallIcons normalIcons records ckInfoTips useInfoTips @@ -535,6 +587,73 @@ return .true +/** onBeginEdit() + * + * The event handler for the label begin edit event, invoked when the user + * initiates a label editing operation. + * + * When the label editing is initiated, the operating system creates and + * postitions a edit control, but doesn't show it. The system then sends the + * label begin edit notification. Here we have access to the edit control, + * which could be customized by using the typical methods of the edit object. + * + * In addition, the edit operation can be vetoed by returning false. I.e., + * return true to allow the editing, and false to disallow it. To demonstrate + * this, we check if the record is editable and if it is not we disallow the + * label editing operation by returning false from this event handler. + */ +::method onBeginEdit unguarded + use arg id, itemIndex, editCtrl, listViewCtrl + + rec = listViewCtrl~getItemData(itemIndex) + if rec~isEditable then return .true + + reply .false + + msg = "The record for" rec~FirstName rec~LastName 'can not be changed.' + title = "Label Edit Error" + j = MessageDialog(msg, self~hwnd, title, , "WARNING") + + return + + +/** onEndEdit() + * + * This is the event handler for the end label edit notification. It is invoked + * when the user ends the label editing operation. If the user canceled the + * operation, then the 'text' argument will be the .nil object. Otherwise it + * will be the text the user entered. + * + * We use this event to validate the label to a degree and to update the record + * for the item when the user edits the label. + */ +::method onEndEdit unguarded + use arg id, itemIndex, text, listViewCtrl + + if text == .nil then return .false + + if text~words == 2 & text~word(1)~right(1) == ',' then do + reply .true + + rec = listViewCtrl~getItemData(itemIndex) + rec~FirstName = text~word(2) + rec~LastName = text~word(1)~strip('T', ',') + + return + end + + reply .false + + msg = "The format for a record label must be" || .endOfLine || - + "last name, comma, first name. For" || .endOfLine || - + "example: Swift, Tom" || .endOfLine~copies(2) || - + "The change is rejected." + + title = "Label Editing Error" + j = MessageDialog(msg, self~hwnd, title, , "WARNING") + + return + /** onColumnClick() * * The event handler for a column click event, invoked when the user clicks on a @@ -579,8 +698,8 @@ expose lv use arg id - -- Get the index of the item with the focus, use the index to retriev the item - -- information and the text associated with it + -- Get the index of the item with the focus, use the index to retrieve the + -- item information and the text associated with it index = lv~focused -- The item's information is returned in the .directory object passed in to @@ -600,8 +719,13 @@ ret = MessageDialog(msg, self~hwnd, "Age Increment", YESNO, INFORMATION) if ret == self~IDYES then do - age = age + 1 + age += 1 lv~setItemText(index, 5, age) + + -- Now we need to update the age in the record for this item. We retrieve + -- the record from the user item data and update the age. + rec = lv~getItemData(index) + rec~age = age end -- Deselect the focused item and move the focus to the first item @@ -618,9 +742,15 @@ * Otherwise, the info tip will contain the text sent back. * * The maxLen argument will be the maximum length allowed for the returned text. - * You should never assume what this lenght is, although it appears to usually + * You should never assume what this length is, although it appears to usually * be 1023. If the text sent back is longer than maxLen, it will automatically * be truncated. + * + * Note that the original versions of this example did not use the user item + * data feature of the list-view. Instead they trackd the records through an + * array. When this example was updated to work with the user item data + * feature, this method was left as is, to show more than one way of associating + * a record with a list-view item. */ ::method onGetInfoTip unguarded expose lv records useInfoTips @@ -638,6 +768,38 @@ return text +/** onSelectionChanged() + * + * This is the event handler for the selection changed event. It is invoked + * each time the selection state of an item changes. We use this event to + * enable or disable the Edit Record push button. The button is only enabled + * when an item is selected, and that item is an editable record. When no item + * is selected, or if the selected item is not editable, then the push button is + * disabled. + * + * The event happens each time a selected item is deselected and each time an + * unselected item is selected. This means that quite often when an item is + * selected there are two events, the old selected item losing its selection and + * the newly selected item gaining the selection. + */ +::method onSelectChanged unguarded + expose haveSelection pbEdit lv + use arg id, itemIndex, state + + if state == 'SELECTED' then haveSelection = .true + else if state == 'UNSELECTED' & lv~selected == -1 then haveSelection = .false + + if \ haveSelection then do + pbEdit~disable + end + else if state == 'SELECTED' then do + -- We have a selection and an item was just selected, see if it is editable: + rec = lv~getItemData(itemIndex) + if rec~isEditable then pbEdit~enable + else pbEdit~disable + end + + /** addRecord() * * Used to add an item to the list view. @@ -655,11 +817,60 @@ if rec~sex = "F" then iconSex = 1 index = lv~addRow(, iconSex, rec~lastName', 'rec~firstName, rec~street, rec~city, rec~state, rec~ZipCode, rec~age) - lv~setItemData(index, rec~firstName rec~lastName) + lv~setItemData(index, rec) if newRecord then records~append(rec) +/** getSelectedRecord() + * + * The owner dialog, the top-level dialog, invokes this method to get access to + * the data record of the currently selected item. + * + * Because the program only enables the 'Edit Record' button when an item that + * is editable is selected, we do not need to do a lot of checks here. We + * simply get the selected index, get the user item data for that index, and + * send the record back. + */ +::method getSelectedRecord + expose lv + return lv~getItemData(lv~selected) + + +/** refreshSelectedRecord() + * + * This method is invoked by the owner dialog to notify us that the data in a + * record has been changed. We simply get the record for the selected item and + * modify the item with the record data. + * + * Because of the way the program is structured, there must be a selected item. + * We check anyway that the selected index is value + */ +::method refreshSelectedItem + expose lv pbEdit + + index = lv~selected + if index == -1 then return .false + + rec = lv~getItemData(index) + + iconSex = 0 + if rec~sex = "F" then iconSex = 1 + + lv~modify(index, 0, rec~lastName', 'rec~firstName, iconSex) + lv~modify(index, 1, rec~street) + lv~modify(index, 2, rec~city) + lv~modify(index, 3, rec~state) + lv~modify(index, 4, rec~zipCode) + lv~modify(index, 5, rec~age) + + -- The is editable status of the record could have changed. + if rec~isEditable then pbEdit~enable + else pbEdit~disable + + return .true + + /** leaving() * * The ooDialog framework invokes the leaving method automatically when a dialog @@ -685,22 +896,49 @@ ::class 'AddressDialog' subclass RcDialog ::method init - forward class (super) continue + expose rec + self~init:super(arg(1), arg(2)) if self~initCode <> 0 then return self~initCode + if arg(3, 'E') then rec = arg(3) + else rec = .nil + -- Initialize the data attributes. These attributes are added automatically -- to this dialog by the ooDialog framework. The attributes are used to -- reflect the state of the underlying dialog controls. - self~IDC_RB_MALE=1 - self~IDC_RB_FEMALE=0 - self~IDC_EDIT_FNAME= '' - self~IDC_EDIT_LNAME= '' - self~IDC_EDIT_STREET= '' - self~IDC_EDIT_CITY= '' - self~IDC_EDIT_STATE= '' - self~IDC_EDIT_ZIPCODE= '' - self~IDC_EDIT_AGE= '' + -- + -- If we have a record, we are in edit mode, otherwise we are in add mode. + if rec == .nil then do + self~IDC_RB_MALE = 1 + self~IDC_RB_FEMALE = 0 + self~IDC_EDIT_FNAME = '' + self~IDC_EDIT_LNAME = '' + self~IDC_EDIT_STREET = '' + self~IDC_EDIT_CITY = '' + self~IDC_EDIT_STATE = '' + self~IDC_EDIT_ZIPCODE = '' + self~IDC_EDIT_AGE = '' + self~IDC_CHK_EDITABLE = 1 + end + else do + if rec~Sex == 'M' then do + self~IDC_RB_MALE = 1 + self~IDC_RB_FEMALE = 0 + end + else do + self~IDC_RB_MALE = 0 + self~IDC_RB_FEMALE = 1 + end + self~IDC_EDIT_FNAME = rec~FirstName + self~IDC_EDIT_LNAME = rec~Lastname + self~IDC_EDIT_STREET = rec~Street + self~IDC_EDIT_CITY = rec~City + self~IDC_EDIT_STATE = rec~State + self~IDC_EDIT_ZIPCODE = rec~ZipCode + self~IDC_EDIT_AGE = rec~Age + self~IDC_CHK_EDITABLE = rec~isEditable + end return self~initCode Modified: ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.h =================================================================== --- ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.h 2012-11-04 05:09:22 UTC (rev 8556) +++ ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.h 2012-11-04 16:40:23 UTC (rev 8557) @@ -56,4 +56,6 @@ #define IDC_EDIT_AGE 307 #define IDC_EDIT_STATE 308 #define IDC_EDIT_ZIPCODE 309 +#define IDC_PB_EDITRECORD 1001 #define IDC_CK_INFOTIPS 1002 +#define IDC_CHK_EDITABLE 1003 Modified: ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.rc =================================================================== --- ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.rc 2012-11-04 05:09:22 UTC (rev 8556) +++ ooDialog/trunk/examples/propertySheet.tabs/rc/oodListViews.rc 2012-11-04 16:40:23 UTC (rev 8557) @@ -36,7 +36,8 @@ /*----------------------------------------------------------------------------*/ #include <windows.h> -#include <CommCtrl.h> +#include <winuser.h> +#include <commctrl.h> #include "oodListViews.h" @@ -62,6 +63,7 @@ EDITTEXT IDC_EDIT_AGE, 54, 91, 23, 12, ES_NUMBER AUTORADIOBUTTON "Male", IDC_RB_MALE, 100, 91, 27, 12, WS_GROUP AUTORADIOBUTTON "Female", IDC_RB_FEMALE, 141, 91, 41, 12 + AUTOCHECKBOX "Record can be edited", IDC_CHK_EDITABLE, 11, 116, 84, 14, BS_VCENTER DEFPUSHBUTTON "OK", IDOK, 155, 116, 50, 14 PUSHBUTTON "Cancel", IDCANCEL, 221, 117, 50, 14 } @@ -76,11 +78,12 @@ { CONTROL "", IDC_TAB, WC_TABCONTROL, WS_TABSTOP, 10, 10, 380, 175 AUTOCHECKBOX "Use Info Tips", IDC_CK_INFOTIPS, 10, 194, 81, 13 - PUSHBUTTON "Backward", IDC_PB_BACKWARD, 10, 218, 62, 14 - PUSHBUTTON "Forward", IDC_PB_FORWARD, 77, 218, 62, 14 - PUSHBUTTON "Add Record", IDC_PB_ADDRECORD, 167, 218, 62, 14 - DEFPUSHBUTTON "OK", IDOK, 261, 218, 62, 14 - PUSHBUTTON "Cancel", IDCANCEL, 328, 218, 62, 14 + PUSHBUTTON "Backward", IDC_PB_BACKWARD, 10, 218, 55, 14 + PUSHBUTTON "Forward", IDC_PB_FORWARD, 72, 218, 55, 14 + PUSHBUTTON "Add Record", IDC_PB_ADDRECORD, 134, 218, 55, 14 + PUSHBUTTON "Edit Record", IDC_PB_EDITRECORD, 197, 218, 55, 14 + DEFPUSHBUTTON "OK", IDOK, 275, 218, 55, 14 + PUSHBUTTON "Cancel", IDCANCEL, 335, 218, 55, 14 } @@ -90,5 +93,5 @@ STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILDWINDOW FONT 8, "Ms Shell Dlg" { - CONTROL "", IDC_LISTVIEW, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_EDITLABELS | LVS_LIST, 3, 3, 368, 154 + CONTROL "", IDC_LISTVIEW, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_EDITLABELS | LVS_LIST | LVS_SHOWSELALWAYS, 3, 3, 368, 154 } Modified: ooDialog/trunk/ooDialog/oodMessaging.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodMessaging.cpp 2012-11-04 05:09:22 UTC (rev 8556) +++ ooDialog/trunk/ooDialog/oodMessaging.cpp 2012-11-04 16:40:23 UTC (rev 8557) @@ -1811,6 +1811,7 @@ msgReply = requiredBooleanReply(c, pcpbd, msgReply, methodName, false); if ( msgReply == NULL ) { + setWindowPtr(pcpbd->hDlg, DWLP_MSGRESULT, TRUE); return ReplyFalse; } |
From: <mie...@us...> - 2012-11-08 01:00:29
|
Revision: 8574 http://sourceforge.net/p/oorexx/code-0/8574 Author: miesfeld Date: 2012-11-08 01:00:26 +0000 (Thu, 08 Nov 2012) Log Message: ----------- ooDialog - update release notes, and trivial comment change. Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/ooDialog/oodListView.cpp Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-11-08 00:41:59 UTC (rev 8573) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-11-08 01:00:26 UTC (rev 8574) @@ -1,17 +1,26 @@ Release Notes ooDialog 4.2.1 (preview) ====================================== -NOTE: This preview version is a SNAPSHOT of the current development in - ooDialog. It is not a beta release, or even an alpha release. - The build is placed here to allow to interested parties to toy - with some of the new features coming up. Devlopment work is still - on-going and new interfaces are not guarenteed. Method names and - or method arguments of features currently in development may - change before a final release. +NOTE: +------------------------------------------------------------------------ +The ooDialog 4.2.1 preview version is a SNAPSHOT of the current +development in ooDialog. It is not a beta release, or even an alpha +release. The build is placed here to allow to interested parties to try +and / or use some of the new features coming up in ooDialog 4.2.1. +Devlopment work is still on-going and new interfaces are not guarenteed. +Method names and or method arguments of features currently in +development may change before a final release. +Please feel free to open bugs on SourceForge for bugs found in this +preview and / or discuss changes or improvements to the new features on +the ooRexx User's list. +------------------------------------------------------------------------ +ENDNOTE: + The ooDialog 4.2.1 release is focused on improvements to the ListView -class in ooDialog. In addition to bug fixes, this release contains a -number of enhancement to the list-view implementation in ooDialog. +and TreeView classes in ooDialog. In addition to bug fixes, this +release contains a number of enhancements to both the list-view and +tree-view implementations in ooDialog. ooDialog 4.2.1 can be installed to any ooRexx installation, 4.1.0 or later. @@ -73,7 +82,9 @@ * #1138 MessageDialog: Failure in system service +* #1141 ooDialog - connecting system menu command events can fail + Feature Requests in ooDialog: ----------------------------- @@ -101,7 +112,11 @@ * #490 ooDialog - ListView class should support info tips +* #493 ooDialog - TreeView begin / end label editing could be improved +* #494 ooDialog - ListView begin / end label editing could be improved + + New Functionality in ooDialog: ------------------------------ @@ -215,11 +230,19 @@ * the KEYDOWNEX event is added. + * the BEGINEDIT event is enhanced + + * the ENDEDIT event is enhanced + connectTreeViewItem() * the KEYDOWNEX event is added. + * the BEGINEDIT event is enhanced + * the ENDEDIT event is enhanced + + New samples: ------------ @@ -242,11 +265,20 @@ ------------- The ListView Control chapter in the ooDialog Reference Manual has been -reviewed and corrected for accuracy. The entire chapter has been -updated to match the format and style that was introduced in the rework -of the manual done for ooDialog 4.2.0 +partially reviewed and corrected for accuracy. Parts of the chapter +have been updated to match the format and style that was introduced in +the rework of the manual done for ooDialog 4.2.0 +The TreeView Control chapter in the ooDialog Reference Manual has been +partially reviewed and corrected for accuracy. Parts of the chapter +have been updated to match the format and style that was introduced in +the rework of the manual done for ooDialog 4.2.0 + +The documentation for the connectListViewEvent and connectTreeViewEvent +methods have been enhanced. + + Known Problems, "Gotchas," and Solutions with Independent Installations ======================================================================== Modified: ooDialog/trunk/ooDialog/oodListView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodListView.cpp 2012-11-08 00:41:59 UTC (rev 8573) +++ ooDialog/trunk/ooDialog/oodListView.cpp 2012-11-08 01:00:26 UTC (rev 8574) @@ -2730,7 +2730,7 @@ * value, we need to replace the current value with the new value. * * 3.) There is a current lParam user data set and it is a full row - * object. In this case, if lvItem contains a lParma user data value + * object. In this case, if lvItem contains a lParm user data value * we need to update the current value with the new value. If not, * we need to merge the new lvItem into the full row item. */ |
From: <mie...@us...> - 2012-11-22 03:45:10
|
Revision: 8611 http://sourceforge.net/p/oorexx/code-0/8611 Author: miesfeld Date: 2012-11-22 03:45:07 +0000 (Thu, 22 Nov 2012) Log Message: ----------- #419 Add Tooltip control See ticket [Feature-Requests:#419] Modified Paths: -------------- ooDialog/trunk/examples/controls/toolTip.rex ooDialog/trunk/ooDialog/APICommon.cpp ooDialog/trunk/ooDialog/APICommon.hpp ooDialog/trunk/ooDialog/PlainBaseDialog.cls ooDialog/trunk/ooDialog/oodCommon.hpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp ooDialog/trunk/ooDialog/oodToolTip.cpp Modified: ooDialog/trunk/examples/controls/toolTip.rex =================================================================== --- ooDialog/trunk/examples/controls/toolTip.rex 2012-11-21 04:06:46 UTC (rev 8610) +++ ooDialog/trunk/examples/controls/toolTip.rex 2012-11-22 03:45:07 UTC (rev 8611) @@ -77,10 +77,10 @@ count = 0 - ttOk = self~newToolTip(IDC_TT_Test1, 'BALLOON') - ttEsc = self~newToolTip(IDC_TT_Test2) - ttTest = self~newToolTip(IDC_TT_TEST3) - tt = self~newToolTip(IDC_TT_MAIN) + ttOk = self~createToolTip(IDC_TT_Test1, 'BALLOON') + ttEsc = self~createToolTip(IDC_TT_Test2) + ttTest = self~createToolTip(IDC_TT_TEST3) + tt = self~createToolTip(IDC_TT_MAIN) clRect = self~clientRect hMidpoint = trunc((clRect~right - clRect~left) / 2) + clRect~left Modified: ooDialog/trunk/ooDialog/APICommon.cpp =================================================================== --- ooDialog/trunk/ooDialog/APICommon.cpp 2012-11-21 04:06:46 UTC (rev 8610) +++ ooDialog/trunk/ooDialog/APICommon.cpp 2012-11-22 03:45:07 UTC (rev 8611) @@ -456,11 +456,27 @@ return NULLOBJECT; } -void wrongObjInArrayException(RexxThreadContext *c, size_t argPos, size_t index, CSTRING obj, RexxObjectPtr actual) +/** + * Index <index> of the array, argument <argPos>, must be <msg>; found + * "<actual>" + * + * Index 2 of the array, argument 2, must be exactly one of keywords POP or + * SHOW; found "POINT" + * + * + * Raises 88.900 + * + * @param c Thread context we are executing in. + * @param argPos Array argument position. + * @param index Index in array + * @param msg Some string message, or object + * @param actual Actual Rexx object, in string format. + */ +void wrongObjInArrayException(RexxThreadContext *c, size_t argPos, size_t index, CSTRING msg, CSTRING actual) { char buffer[256]; snprintf(buffer, sizeof(buffer), "Index %d of the array, argument %d, must be %s; found \"%s\"", - index, argPos, obj, c->ObjectToStringValue(actual)); + index, argPos, msg, actual); userDefinedMsgException(c, buffer); } Modified: ooDialog/trunk/ooDialog/APICommon.hpp =================================================================== --- ooDialog/trunk/ooDialog/APICommon.hpp 2012-11-21 04:06:46 UTC (rev 8610) +++ ooDialog/trunk/ooDialog/APICommon.hpp 2012-11-22 03:45:07 UTC (rev 8611) @@ -67,6 +67,7 @@ extern void numberTooSmallException(RexxThreadContext *c, int pos, int min, RexxObjectPtr actual); extern void notNonNegativeException(RexxThreadContext *c, size_t pos, RexxObjectPtr actual); extern void notPositiveException(RexxThreadContext *c, size_t pos, RexxObjectPtr actual); +extern void wrongObjInArrayException(RexxThreadContext *c, size_t argPos, size_t index, CSTRING msg, CSTRING actual); extern void wrongObjInArrayException(RexxThreadContext *c, size_t argPos, size_t index, CSTRING obj, RexxObjectPtr actual); extern void wrongObjInArrayException(RexxThreadContext *c, size_t argPos, size_t index, CSTRING obj); extern void wrongObjInDirectoryException(RexxThreadContext *c, int argPos, CSTRING index, CSTRING needed, RexxObjectPtr actual); @@ -233,7 +234,28 @@ return NULLOBJECT; } + /** + * Index <index> of the array, argument <argPos>, must be <msg>; found + * "<actual>" + * + * Index 2 of the array, argument 2, must be exactly one of keywords POP or + * SHOW; found "POINT" + * + * Raises 88.900 + * + * @param c Thread context we are executing in. + * @param argPos Array argument position. + * @param index Index in array + * @param msg Some string message, or object namee + * @param actual Actual Rexx object, + */ +inline void wrongObjInArrayException(RexxThreadContext *c, size_t argPos, size_t index, CSTRING msg, RexxObjectPtr actual) +{ + wrongObjInArrayException(c, argPos, index, msg, c->ObjectToStringValue(actual)); +} + +/** * Index, <index>, of argument <pos> must be one of <list>; found "<actual>" * * Index, PART, of argument 1 must be one of calendar, next, prev, or none; Modified: ooDialog/trunk/ooDialog/PlainBaseDialog.cls =================================================================== --- ooDialog/trunk/ooDialog/PlainBaseDialog.cls 2012-11-21 04:06:46 UTC (rev 8610) +++ ooDialog/trunk/ooDialog/PlainBaseDialog.cls 2012-11-22 03:45:07 UTC (rev 8611) @@ -836,6 +836,7 @@ ::method hasMenuBar return self~menuBar \== .nil & self~isLinked +::method createToolTip unguarded external "LIBRARY oodialog pbdlg_createToolTip" ::method newStatic unguarded external "LIBRARY oodialog pbdlg_newControl" ::method newPushButton unguarded external "LIBRARY oodialog pbdlg_newControl" ::method newRadioButton unguarded external "LIBRARY oodialog pbdlg_newControl" Modified: ooDialog/trunk/ooDialog/oodCommon.hpp =================================================================== --- ooDialog/trunk/ooDialog/oodCommon.hpp 2012-11-21 04:06:46 UTC (rev 8610) +++ ooDialog/trunk/ooDialog/oodCommon.hpp 2012-11-22 03:45:07 UTC (rev 8611) @@ -443,6 +443,26 @@ * The specified method, built-in function, or external routine exists, * but you used it incorrectly. * + * The "methName" method can not be invoked on "objectName" when the Windows + * dialog does not exist. + * + * The createToolTip method can not be invoked on a StyleDlg when the Windows + * dialog does not exist. + * + * @param c + * @param rxDlg + */ +inline RexxObjectPtr noWindowsDialogException(RexxMethodContext *c, CSTRING methName, RexxObjectPtr rxDlg) +{ + return methodCanNotBeInvokedException(c, methName, rxDlg, "Windows dialog does not exist"); +} + +/** + * 93.900 + * Error 93 - Incorrect call to method + * The specified method, built-in function, or external routine exists, + * but you used it incorrectly. + * * The "methName" method can not be invoked on "objectName" when the parent * Windows dialog does not exist. * Modified: ooDialog/trunk/ooDialog/oodPackageEntry.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-11-21 04:06:46 UTC (rev 8610) +++ ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-11-22 03:45:07 UTC (rev 8611) @@ -607,8 +607,9 @@ REXX_METHOD_PROTOTYPE(pbdlg_getControlData); REXX_METHOD_PROTOTYPE(pbdlg_setControlData); REXX_METHOD_PROTOTYPE(pbdlg_getTextSizeDlg); +REXX_METHOD_PROTOTYPE(pbdlg_createToolTip); +REXX_METHOD_PROTOTYPE(pbdlg_newToolTip); REXX_METHOD_PROTOTYPE(pbdlg_newControl); -REXX_METHOD_PROTOTYPE(pbdlg_newToolTip); REXX_METHOD_PROTOTYPE(pbdlg_getNewControl); REXX_METHOD_PROTOTYPE(pbdlg_putControl); REXX_METHOD_PROTOTYPE(pbdlg_dumpMessageTable); @@ -1642,8 +1643,9 @@ REXX_METHOD(pbdlg_doMinMax, pbdlg_doMinMax), REXX_METHOD(pbdlg_setTabGroup, pbdlg_setTabGroup), REXX_METHOD(pbdlg_stopIt, pbdlg_stopIt), + REXX_METHOD(pbdlg_createToolTip, pbdlg_createToolTip), + REXX_METHOD(pbdlg_newToolTip, pbdlg_newToolTip), REXX_METHOD(pbdlg_newControl, pbdlg_newControl), - REXX_METHOD(pbdlg_newToolTip, pbdlg_newToolTip), REXX_METHOD(pbdlg_getNewControl, pbdlg_getNewControl), REXX_METHOD(pbdlg_putControl, pbdlg_putControl), REXX_METHOD(pbdlg_dumpMessageTable, pbdlg_dumpMessageTable), Modified: ooDialog/trunk/ooDialog/oodToolTip.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodToolTip.cpp 2012-11-21 04:06:46 UTC (rev 8610) +++ ooDialog/trunk/ooDialog/oodToolTip.cpp 2012-11-22 03:45:07 UTC (rev 8611) @@ -335,6 +335,9 @@ */ #define TOOLTIP_CLASS "ToolTip" +#define TOOLTIP_CREATED_MSG "when the underlying Windows ToolTip has already been created" +#define TOOLTIP_NOT_CREATED_MSG "when the underlying Windows ToolTip has not been created" +#define WRONG_EVENT_NAME_MSG "exactly one of the keywords: RELAY, NEEDTEXT, SHOW, POP, LINKCLICK, or NORELAY" static bool lazyInitToolTipTable(RexxMethodContext *c, pCPlainBaseDialog pcpbd) { @@ -423,8 +426,8 @@ if ( StrStrI(flags, "ALWAYSTIP" ) != NULL ) style |= TTS_ALWAYSTIP; if ( StrStrI(flags, "BALLOON" ) != NULL ) style |= TTS_BALLOON; + if ( StrStrI(flags, "CLOSE" ) != NULL ) style |= TTS_CLOSE; if ( StrStrI(flags, "NOANIMATE" ) != NULL ) style |= TTS_NOANIMATE; - if ( StrStrI(flags, "CLOSE" ) != NULL ) style |= TTS_CLOSE; if ( StrStrI(flags, "NOFADE" ) != NULL ) style |= TTS_NOFADE; if ( StrStrI(flags, "NOPREFIX" ) != NULL ) style |= TTS_NOPREFIX; if ( StrStrI(flags, "USEVISUALSTYLE") != NULL ) style |= TTS_USEVISUALSTYLE; @@ -622,7 +625,7 @@ } -static uint32_t matchEvent2index(RexxMethodContext *c, CSTRING evtName, CSTRING *mthName, size_t i) +static uint32_t matchEvent2index(RexxMethodContext *c, CSTRING evtName, CSTRING *mthName, size_t i, size_t argPos) { if ( StrCmpI(evtName, "RELAY") == 0 ) { @@ -654,8 +657,11 @@ *mthName = ""; return RE_NORELAY_IDX; } - - return OOD_ID_EXCEPTION; + else + { + wrongObjInArrayException(c->threadContext, argPos, i, WRONG_EVENT_NAME_MSG, evtName); + return OOD_ID_EXCEPTION; + } } void freeRelayData(pSubClassData pSCData) @@ -986,15 +992,13 @@ } -/** PlainBaseDialog::newToolTip() +/** PlainBaseDialog::createToolTip() * * Creates the Windows tool tip control and instantiates the Rexx ToolTip * object. * - * @param context * @param rxID * @param styleFlags - * @param pcpbd * * @return The Rexx ToolTip object on success, the .nil object on error. * @@ -1006,28 +1010,34 @@ * * Sets the .systemErrorCode. * - * @note All other dialog controls are instantiated through pbdlg_newControl - * which carries the legacy baggage of having to accomadate the - * deprecated CategoryDialog. The newer ToolTip control has a number of - * differences from other dialog controls, so it has its own 'new' method - * here. The newToolTip() method is still a PlainBaseDialog method, we - * just put it here to keep the ToolTip stuff together. We need to - * remember that the context is not the DialogControl context, it is the - * PlainBaseDialog context. + * @remarks All other dialog controls are instantiated through pbdlg_newControl + * which carries the legacy baggage of having to accomadate the + * deprecated CategoryDialog. The newer ToolTip control has a number + * of differences from other dialog controls, so it has its own + * 'create' method here and its own 'new' method below. Both methods + * are still a PlainBaseDialog method, we just put them here to keep + * the ToolTip stuff together. We need to remember that the context + * is not the DialogControl context, it is the PlainBaseDialog + * context. * - * Tool tip controls are different than most other Window controls in - * that they are actually popup windows owned by the dialog, rather than - * child windows of the dialog. Because of this we need to keep track of - * them by adding them to a table. + * Tool tip controls are different than most other Window controls in + * that they are actually popup windows owned by the dialog, rather + * than child windows of the dialog. Because of this we need to keep + * track of them by adding them to a table. * - * Because they are popup windows, we can not find an existing tool tip - * through GetDlgItem(). So, we add each created tool tip to a table and - * look up an existing tool tip through its ID. The sole purpose of this - * is to allow the Rexx programmer to do: newToolTip(ID) at any point in - * her program and get back the same object, as is possible with other - * dialog controls. + * Because they are popup windows, we can not find an existing tool + * tip through GetDlgItem(). So, we add each created tool tip to a + * table in createToolTip() and look up an existing tool tip through + * its ID for the newToolTip() method. The sole purpose of this is to + * allow the Rexx programmer to do: newToolTip(ID) at any point in her + * program and get back the same object, as is possible with other + * dialog controls. + * + * We raise a syntax condition if the user invokes createToolTip using + * an already existing ToolTip ID and raise a syntax condition if the + * user invokes newToolTip() on a non-existent ToolTip. */ -RexxMethod3(RexxObjectPtr, pbdlg_newToolTip, RexxObjectPtr, rxID, OPTIONAL_CSTRING, styleFlags, CSELF, pCSelf) +RexxMethod3(RexxObjectPtr, pbdlg_createToolTip, RexxObjectPtr, rxID, OPTIONAL_CSTRING, styleFlags, CSELF, pCSelf) { oodResetSysErrCode(context->threadContext); @@ -1041,6 +1051,13 @@ } pCPlainBaseDialog pcpbd = (pCPlainBaseDialog)pCSelf; + HWND hDlg = pcpbd->hDlg; + if ( hDlg == NULL ) + { + noWindowsDialogException(context, "createToolTip", pcpbd->rexxSelf); + goto out; + } + uint32_t id = oodResolveSymbolicID(context->threadContext, pcpbd->rexxSelf, rxID, -1, 1, true); if ( id == OOD_ID_EXCEPTION ) { @@ -1055,7 +1072,7 @@ PTOOLTIPTABLEENTRY ptte = findToolTipForID(pcpbd, id); if ( ptte != NULL ) { - toolTip = ptte->rexxSelf; + methodCanNotBeInvokedException(context, "createToolTip", pcpbd->rexxSelf, TOOLTIP_CREATED_MSG); goto out; } @@ -1066,7 +1083,6 @@ } uint32_t style = parseToolTipStyle(styleFlags); - HWND hDlg = pcpbd->hDlg; HWND hToolTip = NULL; // Tool tips need to be created on the same thread as the dialog window procedure. @@ -1120,6 +1136,88 @@ } +/** PlainBaseDialog::newToolTip() + * + * Returns an already instantiated Rexx ToolTip object. + * + * @param rxID The resource ID of the ToolTip. + * + * @return The Rexx ToolTip object on success, the .nil object on error. + * + * @note ToolTip controls are somewhat different than other dialog controls in + * that they are not part of the dialog template, but rather independent + * windows owned by the dialog. Because of this, the underlying ToolTip + * control needs to be created by the programmer using the createToolTip + * method, after the underlying dialog has been created. + * + * The createToolTip() method, creates the underlying ToolTip, + * instantiates the Rexx object, and returns it. The newToolTip() method + * simply returns the alread instantiated Rexx object, as the other newXX + * methods do. + * + * @note All other dialog controls are instantiated through pbdlg_newControl + * which carries the legacy baggage of having to accomadate the + * deprecated CategoryDialog. The newer ToolTip control has a number of + * differences from other dialog controls, so it has its own 'new' method + * here. The newToolTip() method is still a PlainBaseDialog method, we + * just put it here to keep the ToolTip stuff together. We need to + * remember that the context is not the DialogControl context, it is the + * PlainBaseDialog context. + * + * Because ToolTips are popup windows, we can not find an existing tool + * tip through GetDlgItem(). So, each created tool tip is added to a + * table and here, we look up an existing tool tip through its ID. The + * sole purpose of this is to allow the Rexx programmer to do: + * newToolTip(ID) at any point in her program and get back the same + * object, as is possible with other dialog controls. + */ +RexxMethod2(RexxObjectPtr, pbdlg_newToolTip, RexxObjectPtr, rxID, CSELF, pCSelf) +{ + oodResetSysErrCode(context->threadContext); + + RexxObjectPtr toolTip = TheNilObj; + CREATETOOLTIP ctt = {0}; + + if ( pCSelf == NULL ) + { + baseClassInitializationException(context); + goto out; + } + pCPlainBaseDialog pcpbd = (pCPlainBaseDialog)pCSelf; + + HWND hDlg = pcpbd->hDlg; + if ( hDlg == NULL ) + { + noWindowsDialogException(context, "newToolTip", pcpbd->rexxSelf); + goto out; + } + + uint32_t id = oodResolveSymbolicID(context->threadContext, pcpbd->rexxSelf, rxID, -1, 1, true); + if ( id == OOD_ID_EXCEPTION ) + { + goto out; + } + + if ( pcpbd->ToolTipTab == NULL ) + { + methodCanNotBeInvokedException(context, "newToolTip", pcpbd->rexxSelf, TOOLTIP_NOT_CREATED_MSG); + goto out; + } + + PTOOLTIPTABLEENTRY ptte = findToolTipForID(pcpbd, id); + if ( ptte == NULL ) + { + methodCanNotBeInvokedException(context, "newToolTip", pcpbd->rexxSelf, TOOLTIP_NOT_CREATED_MSG); + goto out; + } + + toolTip = ptte->rexxSelf; + +out: + return toolTip; +} + + /** ToolTip::activate() * * Activates or deactivates this tool tip. @@ -1166,8 +1264,10 @@ * @param flags [optional] Keywords for the TTF_* flags. If omitted flags are * automatically set to TTF_IDISHWND | TTF_SUBCLASS. If not * omitted, flags are set to whatever is specified. However, - * TTF_IDISHWND is always set. (Because uID is always set to - * hwnd of tool. + * TTF_IDISHWND and TTF_SUBCLASS are always set. (Because uID is + * always set to hwnd of tool, and for the simple case that + * addTool() is intended for, the dialog control should always be + * subclassed.) * * @param userData [optional] A user data value to be associated with the * tool. Note that the value is associated with the tool, not @@ -1219,13 +1319,9 @@ text = LPSTR_TEXTCALLBACK; } - uint32_t flags = TTF_IDISHWND; - if ( argumentOmitted(3) ) + uint32_t flags = TTF_IDISHWND | TTF_SUBCLASS; + if ( argumentExists(3) ) { - flags |= TTF_SUBCLASS; - } - else - { flags |= keyword2ttfFlags(_flags); } @@ -2200,7 +2296,7 @@ CSTRING mthName; CSTRING evtName = context->ObjectToStringValue(eventName); - uint32_t idx = matchEvent2index(context, evtName, &mthName, i); + uint32_t idx = matchEvent2index(context, evtName, &mthName, i, 2); if ( idx == OOD_ID_EXCEPTION ) { goto err_out; @@ -3010,15 +3106,19 @@ /** ToolInfo::init() * - * @param dlg [required] Dialog ojbect. May be a Buffer object to create - * a .ToolInfo from native code. I + * @param hwndObj [required] Tool hwnd object. May be a Buffer object to + * create a .ToolInfo from native code. * - * @param uID [optional] + * @param rxID [optional] * - * @param text [optional] + * @param text [optional] * - * @param flags [optional] + * @param flags [optional] * + * @param rect [optional] + * + * @param userData [optional] + * * @param _resource [reserved] This is reserved for a future enhancement. * If we ever add the ability to use string resources to the * .Resource class, then this argument will be a .Resource @@ -3027,11 +3127,12 @@ * be a resource identifier. For now it is ignored. * * @remarks Note that genericToolID will set the TTF_IDISHWND flag when it - * determines that the uID filed of the TOOLINFO struct is the hwnd - * of a dialog control. So, we need to or the return from - * keyword2ttfflags() with the existing setting. It may be that the - * user could incorrectly add the TTF_IDISHWND flag and cause a crash - * if the uID is not a hwnd. + * determines that the uID field of the TOOLINFO struct is the hwnd + * of a dialog control. So, we need to || (binary or) the return + * from keyword2ttfflags() with the existing setting. However, it + * may be that the user incorrectly adds the TTF_IDISHWND flag and + * cause a crash if the uID is not a hwnd. So, we also try to + * prevent that. * * When creating from native code, set arg 1 to the TOOLINFO buffer, * set arg 2 to the object supplying the hwnd field of the struct, @@ -3041,14 +3142,14 @@ * object. */ RexxMethod7(RexxObjectPtr, ti_init, RexxObjectPtr, hwndObj, OPTIONAL_RexxObjectPtr, rxID, OPTIONAL_CSTRING, text, - OPTIONAL_CSTRING, _flags, OPTIONAL_RexxObjectPtr, userData, OPTIONAL_RexxObjectPtr, _rect, + OPTIONAL_CSTRING, _flags, OPTIONAL_RexxObjectPtr, _rect, OPTIONAL_RexxObjectPtr, userData, OPTIONAL_RexxObjectPtr, _resource) { if ( context->IsBuffer(hwndObj) ) { context->SetObjectVariable("CSELF", hwndObj); context->SetObjectVariable(TOOLINFO_HWND_OBJECT_VAR, rxID); - context->SetObjectVariable(TOOLINFO_UID_OBJECT_VAR, userData); + context->SetObjectVariable(TOOLINFO_UID_OBJECT_VAR, _rect); goto done_out; } @@ -3070,9 +3171,6 @@ context->SetObjectVariable(TOOLINFO_HWND_OBJECT_VAR, hwndSupplier); context->SetObjectVariable(TOOLINFO_UID_OBJECT_VAR, uIDSupplier); - // TODO decide if user must explicitly set this flag or not? Here we remove it. - pTI->uFlags &= ~TTF_IDISHWND; - if ( argumentExists(3) ) { if ( ! setToolInfoText(context, pTI, text, 3, NULLOBJECT) ) @@ -3087,16 +3185,20 @@ if ( argumentExists(4) ) { - pTI->uFlags |= keyword2ttfFlags(_flags); + // If genericToolID() determined that ID is not a hwnd, do not let the + // user add that flag: + + uint32_t flags = keyword2ttfFlags(_flags); + if ( ! (pTI->uFlags & TTF_IDISHWND) ) + { + flags &= ~TTF_IDISHWND; + } + + pTI->uFlags |= flags; } if ( argumentExists(5) ) { - pTI->lParam = (LPARAM)userData; - } - - if ( argumentExists(6) ) - { PRECT r = rxGetRect(context, _rect, 6); if ( r == NULL ) { @@ -3105,10 +3207,16 @@ CopyRect(&pTI->rect, r); } + if ( argumentExists(6) ) + { + pTI->lParam = (LPARAM)userData; + } + done_out: return NULLOBJECT; } + /** ToolInfo::flags [attribute] */ RexxMethod1(RexxStringObject, ti_flags, CSELF, pTI) |
From: <mie...@us...> - 2012-11-29 00:41:21
|
Revision: 8637 http://sourceforge.net/p/oorexx/code-0/8637 Author: miesfeld Date: 2012-11-29 00:41:15 +0000 (Thu, 29 Nov 2012) Log Message: ----------- #419 Add Tooltip control See ticket [Feature-Requests:#419] Add some example ToolTip programs. Modified Paths: -------------- ooDialog/trunk/examples/controls/Makefile.am ooDialog/trunk/install/ooDialog.nsi ooDialog/trunk/ooDialog/oodToolTip.cpp Added Paths: ----------- ooDialog/trunk/examples/controls/ToolTip/ ooDialog/trunk/examples/controls/ToolTip/Makefile.am ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.h ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.rc ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.rex ooDialog/trunk/examples/controls/ToolTip/manageControlTool.h ooDialog/trunk/examples/controls/ToolTip/manageControlTool.rc ooDialog/trunk/examples/controls/ToolTip/manageControlTool.rex ooDialog/trunk/examples/controls/ToolTip/toolTip.rex ooDialog/trunk/examples/controls/musicNote.ico Removed Paths: ------------- ooDialog/trunk/examples/controls/toolTip.rex Modified: ooDialog/trunk/examples/controls/Makefile.am =================================================================== --- ooDialog/trunk/examples/controls/Makefile.am 2012-11-28 04:10:32 UTC (rev 8636) +++ ooDialog/trunk/examples/controls/Makefile.am 2012-11-29 00:41:15 UTC (rev 8637) @@ -37,6 +37,9 @@ .NOTPARALLEL: +SUBDIRS = ToolTip +DIST_SUBDIRS = ToolTip + MAINTAINERCLEANFILES = Makefile.in *~ EXTRA_DIST = *.rex *.h *.rc *.txt Added: ooDialog/trunk/examples/controls/ToolTip/Makefile.am =================================================================== --- ooDialog/trunk/examples/controls/ToolTip/Makefile.am (rev 0) +++ ooDialog/trunk/examples/controls/ToolTip/Makefile.am 2012-11-29 00:41:15 UTC (rev 8637) @@ -0,0 +1,43 @@ +#/*----------------------------------------------------------------------------*/ +#/* */ +#/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +#/* */ +#/* This program and the accompanying materials are made available under */ +#/* the terms of the Common Public License v1.0 which accompanies this */ +#/* distribution. A copy is also available at the following address: */ +#/* http://www.oorexx.org/license.html */ +#/* */ +#/* Redistribution and use in source and binary forms, with or */ +#/* without modification, are permitted provided that the following */ +#/* conditions are met: */ +#/* */ +#/* Redistributions of source code must retain the above copyright */ +#/* notice, this list of conditions and the following disclaimer. */ +#/* Redistributions in binary form must reproduce the above copyright */ +#/* notice, this list of conditions and the following disclaimer in */ +#/* the documentation and/or other materials provided with the distribution. */ +#/* */ +#/* Neither the name of Rexx Language Association nor the names */ +#/* of its contributors may be used to endorse or promote products */ +#/* derived from this software without specific prior written permission. */ +#/* */ +#/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +#/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +#/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +#/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +#/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +#/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +#/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +#/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +#/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +#/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +#/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#/* */ +#/*----------------------------------------------------------------------------*/ + +.NOTPARALLEL: + +MAINTAINERCLEANFILES = Makefile.in *~ + +EXTRA_DIST = *.rex *.h *.rc + Property changes on: ooDialog/trunk/examples/controls/ToolTip/Makefile.am ___________________________________________________________________ Added: svn:eol-style + native Added: ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.h =================================================================== --- ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.h (rev 0) +++ ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.h 2012-11-29 00:41:15 UTC (rev 8637) @@ -0,0 +1,44 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +#ifndef IDC_STATIC +#define IDC_STATIC (-1) +#endif + +#define IDD_TREEVIEW 100 +#define IDC_TREE 1003 +#define IDC_TT 1000 Property changes on: ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.h ___________________________________________________________________ Added: svn:eol-style + native Added: ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.rc =================================================================== --- ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.rc (rev 0) +++ ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.rc 2012-11-29 00:41:15 UTC (rev 8637) @@ -0,0 +1,53 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +#include <windows.h> +#include <winuser.h> +#include <commctrl.h> +#include "customPositionToolTip.h" + + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +IDD_TREEVIEW DIALOGEX 30, 30, 176, 234 +STYLE DS_3DLOOK | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU +CAPTION "Tree View Dialog" +FONT 8, "Ms Shell Dlg", 400, 0, 1 +{ + DEFPUSHBUTTON "OK", IDOK, 61, 210, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 116, 210, 50, 14 + CONTROL "", IDC_TREE, WC_TREEVIEW, WS_TABSTOP | WS_BORDER | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | TVS_INFOTIP, 10, 10, 156, 192 +} Property changes on: ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.rc ___________________________________________________________________ Added: svn:eol-style + native Added: ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.rex =================================================================== --- ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.rex (rev 0) +++ ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.rex 2012-11-29 00:41:15 UTC (rev 8637) @@ -0,0 +1,201 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * ToolTip control example. + * + * This example demonstrates use info tips with a tree-view and do custom + * positiong of the tool tip. + * + * The appearance and functionality of the dialog in this example is exactly the + * same as that produced by the manageControlTool.rex example. It simple shows + * an easier way to achieve the same effect as that example. + * + * Here we use a simple application of the manageAtypicalTool() method. The + * manageControlTool.rex example is provided to better help the ooDialog + * programmer understand the manageAtypicalTool() method. The programmer should + * really examine both example programs. + * + * To customize the positioning of the info tip, we need to write an event + * handler for the ToolTips SHOW event. However, the ToolTip for the tree-views + * info tips is owned by the tree-view. Event notifications are sent to the + * tree-view and our dialog has no knowledge of them. + * + * To fix that, we use the getToolTips() method to get the tree-views ToolTip. + * We then use the manageAtypicalTool() method to monitor the event + * notifications sent to the tree-view and send the SHOW notification to our + * dialog instead of to the tree-view. All other events, including the mouse + * relay event, are left to go to the tree-view. This gives us the same + * functionality as the custom ToolTip that is set up in the manageControlToo + * example, with less work. + */ + + .application~setDefaults('O', 'customPositionToolTip.h', .false) + + dlg = .TreeViewDialog~new('customPositionToolTip.rc', IDD_TREEVIEW) + dlg~execute("SHOWTOP", IDI_DLG_OOREXX) + + +::requires "ooDialog.cls" + +::class 'TreeViewDialog' subclass RcDialog + +::method initDialog + expose currentItem + + tv = self~newTreeView(IDC_TREE) + tv~setItemHeight(20) + + self~connectTreeViewEvent(IDC_TREE, 'GETINFOTIP') + self~populateTree(tv) + + -- Get the ToolTip the tree-view has created and is using. + toolTip = tv~getToolTips + + -- Set up the monitoring of the ToolTip notifications sent to the tree-view. + -- We only want to intercept the SHOW notification. Also, we do not want the + -- automatic monitoring and relaying of the mouse messages. In this way we + -- achieve what we want with minimal interference with the tree-view's + -- ToolTip. + -- + -- We have to use the NORELAY keyword to turn off the automatic + -- relaying of the mouse messages. NORELAY does not connect an event handler, + -- it simply turns relaying off. + + toolTip~manageAtypicalTool(tv, .array~of('NORELAY', 'SHOW')) + + +/** onGetInfoTip() + * + * This is the event handler for the tree-view's GETINFOTIP notification. It is + * invoked when the tree-view wants the text to display for a ToolTip. + * + * Note that we are sent the handle of the tree-view item that the ToolTip is + * for and the user data (item data) for that item. We set the item data for + * each item to the text to display for the ToolTip for that item. Which makes + * this very easy. We just return the userData sent to us. + * + * Note this also. Our onShow() event handler is invoked by our monitoring of + * the ToolTip notifications. That monitor has no knowledge of which item the + * ToolTip is going to be displayed for. So, we use the exposed currentItem + * variable to pass on our knowledge here of which item the ToolTip is going to + * display for. + */ +::method onGetInfoTip unguarded + expose currentItem + use arg id, hItem, text, maxLen, userData + + currentItem = hItem + return userData + + +/** onShow() + * + * This is our event handler for the tree-view's ToolTip SHOW event + * notification. The method is invoked when our process monitoring the + * notifications sent to the tree-view, intercepts the SHOW notification. + * + * Normally the ToolTip window is placed below the item. This often over-laps + * and obscures the other items. What we want is to place the ToolTip window to + * the right and centered with the item. This way nothing is obscured. + * + * The custom positioning of the ToolTip window is straight-forward. We get the + * bounding rectangle of the tree-view item's label, convert the point to client + * coordinates, and then reposition the ToolTip window to where we want it. + * + * Note that we must return .true then so that the ToolTip is informed not to + * position the window in its default position. + */ +::method onShow unguarded + expose currentItem + use arg toolTip, treeView + + r = .Rect~new + if treeView~getItemRect(currentItem, r) then do + treeView~client2screen(r) + + toolTip~setWindowPos(0, r~right + 5, r~top, 0, 0, "NOACTIVATE NOSIZE NOZORDER") + return .true + end + + return .false + + +/** populateTree() + * + * This is a private method used to populate the tree-view control with our + * items. + * + * Note that each item has an item data object assigned to it. In this case the + * object is a string. The string is the text to display for the tool tip for + * that item. + */ +::method populateTree private + use strict arg tv + + hItem = tv~add("Peter", , ,"BOLD EXPANDED", , 'Data unique to Peter.') + + hItem = tv~add(,"Mike", , ,"EXPANDED", , 'Mike talks a lot.') + + data = 'George was famous once.'.endOfLine'He is unknown to my'.endOfLine'niece.' + hItem = tv~add(, ,"George", , , , , data) + + hItem = tv~add(, ,"Monique", , , , , 'Monique has never been to France.') + + hItem = tv~add(, , ,"John", , , , , 'John owns 4 dogs.') + + hItem = tv~add(, ,"Chris", , , , , 'Chris will never be president.') + + hItem = tv~add( , "Maud", , , , , 'Maud likes to bake.') + + hItem = tv~add( , "Ringo", , , , , 'Ringo has a LOT of money.') + + hItem = tv~add("Paul", , ,"BOLD EXPANDED", , "Two roads lead to Paul's house.") + + hItem = tv~add( , "Dave", , , , , 'No one lives with Dave.') + + hItem = tv~add( , "Sam", , , , , 'Sam loves pizza.') + + hItem = tv~add( , "Jeff", , , , , 'Jeff rides his bike to work.') + + hItem = tv~add("Mary", , ,"BOLD EXPANDED", , 'Mary owes $49.50 to her dentist.') + + hItem = tv~add( , "Helen", , , , , 'A closer look at Helen is warranted.') + + hItem = tv~add( , "Michelle", , , , , 'The Toyota Camray belongs to Michelle.') + + hItem = tv~add( , "Diana", , , , , 'Go go Chargers.') Property changes on: ooDialog/trunk/examples/controls/ToolTip/customPositionToolTip.rex ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Added: ooDialog/trunk/examples/controls/ToolTip/manageControlTool.h =================================================================== --- ooDialog/trunk/examples/controls/ToolTip/manageControlTool.h (rev 0) +++ ooDialog/trunk/examples/controls/ToolTip/manageControlTool.h 2012-11-29 00:41:15 UTC (rev 8637) @@ -0,0 +1,44 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +#ifndef IDC_STATIC +#define IDC_STATIC (-1) +#endif + +#define IDD_TREEVIEW 100 +#define IDC_TREE 1003 +#define IDC_TT 1000 Property changes on: ooDialog/trunk/examples/controls/ToolTip/manageControlTool.h ___________________________________________________________________ Added: svn:eol-style + native Added: ooDialog/trunk/examples/controls/ToolTip/manageControlTool.rc =================================================================== --- ooDialog/trunk/examples/controls/ToolTip/manageControlTool.rc (rev 0) +++ ooDialog/trunk/examples/controls/ToolTip/manageControlTool.rc 2012-11-29 00:41:15 UTC (rev 8637) @@ -0,0 +1,53 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +#include <windows.h> +#include <winuser.h> +#include <commctrl.h> +#include "manageControlTool.h" + + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +IDD_TREEVIEW DIALOGEX 30, 30, 176, 234 +STYLE DS_3DLOOK | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU +CAPTION "Tree View Dialog" +FONT 8, "Ms Shell Dlg", 400, 0, 1 +{ + DEFPUSHBUTTON "OK", IDOK, 61, 210, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 116, 210, 50, 14 + CONTROL "", IDC_TREE, WC_TREEVIEW, WS_TABSTOP | WS_BORDER | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS, 10, 10, 156, 192 +} Property changes on: ooDialog/trunk/examples/controls/ToolTip/manageControlTool.rc ___________________________________________________________________ Added: svn:eol-style + native Added: ooDialog/trunk/examples/controls/ToolTip/manageControlTool.rex =================================================================== --- ooDialog/trunk/examples/controls/ToolTip/manageControlTool.rex (rev 0) +++ ooDialog/trunk/examples/controls/ToolTip/manageControlTool.rex 2012-11-29 00:41:15 UTC (rev 8637) @@ -0,0 +1,292 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * ToolTip control example. + * + * This example demonstrates several advanced techniques in using ToolTips. + * + * Typically a single tool is created for a dialog control. This works fine + * for creating tools for, say, buttons. Even if you have 20 buttons, it is + * pretty reasonable to create 20 tools in a ToolTip. + * + * But, what if you want to display a tip for each item in a tree-view? What if + * the tree-view has hundreds, or even thousands, of items. Creating several + * thousand tools is no longer reasonable. One technique is to create one tool + * and dynamically make it appear to be multiple tools. + * + * That technique is demonstrated in this example. We use a tree-view control + * to show the technique. The basic principle is to track where the mouse is, + * and dynamically update the tool each time it moves from one item to another. + * + * Normally you would program this by monitoring the mouse moves and updating + * the tool when the mouse moves require it. To do this, you can not use the + * SUBCLASS flag for the tool, because you need to dynamically update tool + * _before_ the tool sees the mouse move. You would monitor the mouse moves, + * decide whether to update or not the tool, and then forward every mouse move + * on to the tool. For the puposes of discussion, we will refer to the + * forwarding of the mouse moves as 'relaying' the moves. And, actually for the + * ToolTip to work correctly it needs to see all the mouse related messages. + * So, the relaying is really relaying all mouse messages, not just the mouse + * move message. + * + * This presents a problem in ooDialog because mouse messages are sent to the + * window under the mouse, in this case the tree-view. In addition, if we set + * up a tool for the tree-view, but can not use the SUBCLASS flags, the ToolTip + * event notifications are sent to the tree-view, not to our dialog. + * + * In this case, we need a way to monitor the mouse messages sent to the + * tree-view and a way to intercept the ToolTip event notifications that would + * be sent to the tree-view. For ToolTips, ooDialog provides a method, the + * manageAtypicalTool() method, that provides this functionality. + * + * This method monitors all mouse messages and relays the messages to the tool. + * Before it relays the mouse messages to the took, it will invoke a method in + * the Rexx dialog for the relay event. In addition, it intercepts all the + * ToolTip event notifications sent to the dialog control and invokes a method + * in the Rexx dialog for each event. + * + * Of course, the application may not need to have an event handler for all the + * events, or even for the relay event. So, manageAtypicalTool() allows the + * programmer to just connect the events it needs. + * + * Although this example just focuses on a specific use of manageAtypicalTool(), + * the method can be used in any situation where custom ToolTips are needed for + * dialog controls. The same principles that necessitate its use here, will be + * found in many situations. + * + * Note that in this specific case, there is an easier way to produce the same + * results as this example does. The customPositionToolTip.rex example shows + * how to use the easier method. However, this example is very useful in + * showing how the manageAtypicalToo() works. The principles here can be used + * in other situations. + */ + + .application~setDefaults('O', 'manageControlTool.h', .false) + + dlg = .TreeViewDialog~new('manageControlTool.rc', IDD_TREEVIEW) + dlg~execute("SHOWTOP", IDI_DLG_OOREXX) + + +::requires "ooDialog.cls" + +::class 'TreeViewDialog' subclass RcDialog + +::method initDialog + expose currentItem currentLocation currentText + + -- These variables are used to help track which tool needs to be shown. + currentItem = 0 + currentText = '' + currentLocation = 'NOWHERE' + + tv = self~newTreeView(IDC_TREE) + + -- Set up our ToolTip + tt = self~createToolTip(IDC_TT) + + rect = tv~clientRect + + -- We need to specify very precisely the attributes of the tool we are going + -- to add. We can not do that using the addTool() or addToolRect() + -- convenience methods. So we need a ToolInfo object and to use the + -- addToolEx() method. + + toolInfo = .ToolInfo~new(tv, 10, '', 'TRANSPARENT', rect) + tt~addToolEx(toolInfo) + + tt~setMaxTipWidth(250) + + -- Set up our tree-view and populate it. + tv~setItemHeight(20) + self~populateTree(tv) + + -- Now start the monitoring process. + tt~manageAtypicalTool(tv, .array~of('RELAY', 'NEEDTEXT', 'SHOW')) + + +/** onRelay() + * + * This is the event handler for the mouse message relaying event. It is + * invoked by our monitoring process for every mouse message. The method is + * invoked _before_ the monitor relays the mouse message to the ToolTip. + * + * This method is crucial to how this example works. For every mouse message, + * we calculate if the mouse is still over the label of the same item it was + * over previously. If it is not, we hide the ToolTip window by invoking the + * pop(). + * + * After we return form this method, the mouse message is forwarded on to the + * ToolTip to let it do its ToolTip thing. When the ToolTip decides the mouse + * has hovered long enough in one spot, it displays its window. Since we have + * set the current text to the string for the tree-view item when the mouse + * first moved over the item, the correct "tool" text is displayed. + * + * The text to display is actually passed on to the ToolTip from our onNeedTex() + * method. + */ +::method onRelay unguarded + expose currentItem currentText currentLocation + use arg toolTip, pos, mouseMsg, treeView + + -- Determine which, if any, item the mouse is over. + d = treeView~hitTestInfo(pos) + + -- Save the old item and location and sent the current item and location to + -- where the mouse is at this moment. + oldItem = currentItem + oldLocation = currentLocation + currentItem = d~hItem + currentLocation = d~location + + -- If mouse is over a new item or location, hide the ToolTip. Set our + -- current text to the text for the item we are now over. If we are not + -- over the label of an item, set the current text to the empty string. + if oldItem \== currentItem | oldLocation \== currentLocation then do + if currentItem <> 0, currentLocation~wordPos('ONLABEL') <> 0 then do + currentText = treeView~getItemData(currentItem) + end + else do + currentText = '' + end + toolTip~pop + end + + return 0 + + +/** onNeedText() + * + * This is the event handler for the ToolTip's NEEDTEXT event notification. + * + * The notification was actually sent to the tree-view, but, our monitor process + * has intercepted the notification and sent it to us instead of the tree-view. + * + * The real work was already done in the onRelay() method. All we need to do is + * set the TEXT index in the info .Directory object to what the onRelay() method + * set the current text to. + */ +::method onNeedText unguarded + expose currentItem currentText + use arg toolTip, treeView, info, userData, flags + + info~text = currentText + + -- Return false so that the ToolTip does not store the text. We want it to + -- always ask us for the text because the mouse could be over any item. + return .false + + + +/** onShow() + * + * This is our event handler for the ToolTip's SHOW event notification. + * + * The notification was actually sent to the tree-view, but our monitor process + * has intercepted the notificatio and sent it to us instead of the tree-view. + * + * Normally the ToolTip places its window below the tree-view item. This often + * over-laps and obscures the other items. What we want is to place the ToolTip + * window to the right and centered with the item. This way nothing is + * obscured. + * + * The custom positioning of the ToolTip window is straight-forward. We get the + * bounding rectangle of the tree-view item's label, convert the point to client + * coordinates, and then reposition the ToolTip window to where we want it. + * + * Note that we must return .true then so that the ToolTip is informed not to + * position the window in its default position. + */ +::method onShow unguarded + expose currentItem + use arg toolTip, treeView + + r = .Rect~new + if treeView~getItemRect(currentItem, r) then do + treeView~client2screen(r) + + toolTip~setWindowPos(0, r~right + 5, r~top, 0, 0, "NOACTIVATE NOSIZE NOZORDER") + return .true + end + + return .false + + +/** populateTree() + * + * This is a private method used to populate the tree-view control with our + * items. + * + * Note that each item has an item data object assigned to it. In this case the + * object is a string. The string is the text to display for the tool tip for + * that item. + */ +::method populateTree private + use strict arg tv + + hItem = tv~add("Peter", , ,"BOLD EXPANDED", , 'Data unique to Peter.') + + hItem = tv~add(,"Mike", , ,"EXPANDED", , 'Mike talks a lot.') + + data = 'George was famous once.'.endOfLine'He is unknown to my'.endOfLine'niece.' + hItem = tv~add(, ,"George", , , , , data) + + hItem = tv~add(, ,"Monique", , , , , 'Monique has never been to France.') + + hItem = tv~add(, , ,"John", , , , , 'John owns 4 dogs.') + + hItem = tv~add(, ,"Chris", , , , , 'Chris will never be president.') + + hItem = tv~add( , "Maud", , , , , 'Maud likes to bake.') + + hItem = tv~add( , "Ringo", , , , , 'Ringo has a LOT of money.') + + hItem = tv~add("Paul", , ,"BOLD EXPANDED", , "Two roads lead to Paul's house.") + + hItem = tv~add( , "Dave", , , , , 'No one lives with Dave.') + + hItem = tv~add( , "Sam", , , , , 'Sam loves pizza.') + + hItem = tv~add( , "Jeff", , , , , 'Jeff rides his bike to work.') + + hItem = tv~add("Mary", , ,"BOLD EXPANDED", , 'Mary owes $49.50 to her dentist.') + + hItem = tv~add( , "Helen", , , , , 'A closer look at Helen is warranted.') + + hItem = tv~add( , "Michelle", , , , , 'The Toyota Camray belongs to Michelle.') + + hItem = tv~add( , "Diana", , , , , 'Go go Chargers.') Property changes on: ooDialog/trunk/examples/controls/ToolTip/manageControlTool.rex ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Copied: ooDialog/trunk/examples/controls/ToolTip/toolTip.rex (from rev 8635, ooDialog/trunk/examples/controls/toolTip.rex) =================================================================== --- ooDialog/trunk/examples/controls/ToolTip/toolTip.rex (rev 0) +++ ooDialog/trunk/examples/controls/ToolTip/toolTip.rex 2012-11-29 00:41:15 UTC (rev 8637) @@ -0,0 +1,325 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * ToolTip control example. + * + * This example demonstrates some fundemental use of the TooTip control. It + * creates a tool tip for each push button in the dialog and tool tips for some + * rectangular areas in the dialog itself. + * + * There is a 'Test' push button in the dialog. When this button is pushed, + * several short demonstrations are executed that show some of the additional + * ToolTip methods at work. These demonstrations print to the screen using say + * statements. Therefore it is best to run this example program from a standard + * console window so that the output can be seen. + * + */ + + -- Set this application to use the global .constDir Only. Then add our + -- symbolic IDs to the .constDir. + .application~setDefaults('O', , .false) + + .constDir[IDC_TT_MAIN ] = 500 + .constDir[IDC_TT_OK] = 501 + .constDir[IDC_TT_CANCEL] = 502 + .constDir[IDC_TT_TEST] = 503 + .constDir[IDTOOL_DLG_RECT1] = 774 + .constDir[IDTOOL_DLG_RECT2] = 775 + .constDir[IDTOOL_DLG_RECT3] = 776 + .constDir[IDTOOL_DLG_RECT4] = 777 + .constDir[IDC_PB_TEST] = 600 + + -- Instantiate our dialog and execute it. + dlg = .ToolTipDialog~new + dlg~execute("SHOWTOP", IDI_DLG_OOREXX) + + return 0 + + +::requires "ooDialog.cls" + +::class 'ToolTipDialog' subclass UserDialog + + +/** init() + * + * Usual init() method for a UserDialog subclass. We initialize the super class + * and then create the dialog frame to get things started. + * + * We also use this method to create an icon image. This image is used for the + * balloon ToolTip. + */ +::method init + expose icon + forward class (super) continue + + icon = .Image~getImage("musicNote.ico", .Image~toID(IMAGE_ICON), .size~new(16, 16)) + + self~create(30, 30, 257, 123, "ToolTip Example Dialog", "CENTER") + + +/** defineDialog() + * + * Usual defineDialog() method. We add 3 push buttons to the dialog template. + */ +::method defineDialog + + self~createPushButton(IDC_PB_TEST, 10, 99, 50, 14, , "Test", onTest) + self~createPushButton(IDOK, 142, 99, 50, 14, "DEFAULT", "Ok") + self~createPushButton(IDCANCEL, 197, 99, 50, 14, , "Cancel") + + +/** initDialog() + * + * Usual initDialog() method. + * + * However, note that ToolTip controls can not be added to the dialog template. + * They *have* to be created *after* the underlying dialog exists. Typically, + * ToolTips would always be created in the initDialog() method. + */ +::method initDialog unguarded + expose icon pbTest count ttTest + + -- The main tool tip is set up in a private method, so that the code for it + -- can be inspected without distraction. + self~createMainToolTip + + -- Creat a somewhat fancy balloon tool tip for the Ok button. + ttOk = self~createToolTip(IDC_TT_OK, 'BALLOON CLOSE') + ttOk~setTitle("Important Message", icon) + + text = 'Push the'.endOfLine'Ok button'.endOfLine'to end this'.endOfLine'foolishness' + ttOk~addTool(self~newPushButton(IDOK), text) + + -- Create a simple multiline tool tip for the Cancel push button. The tool + -- tip is turned into a multiline tool tip by seeting the max tool tip + -- width. + ttEsc = self~createToolTip(IDC_TT_CANCEL) + ttEsc~addTool(self~newPushButton(IDCANCEL), 'Press Cancel to end the dialog') + + margins = 2 * 4 + s = self~getTextSizePX('Press Cancel') + ttEsc~setMaxTipWidth(s~width + margins) + + -- Create a tool tip for the Test push button. + pbTest = self~newPushButton(IDC_PB_TEST) + + ttTest = self~createToolTip(IDC_TT_TEST) + ttTest~addTool(pbTest) + self~connectToolTipEvent(IDC_TT_TEST, 'NEEDTEXT') + + count = 0 + + +/** createMainToolTip() + * + * This is a private method we use to set up the main ToolTip. We do the set + * up here so that the code for the set up can be studied without any other + * distractions. + */ +::method createMainToolTip private + expose tt clRect1 clRect2 clRect3 clRect4 + + tt = self~createToolTip(IDC_TT_MAIN) + + -- We divide the client area of the dialog into 4 quadrants and then add a + -- tool for each quandrant to the main tool tip. + + clRect = self~clientRect + hMidpoint = trunc((clRect~right - clRect~left) / 2) + clRect~left + vMidpoint = trunc((clRect~bottom - clRect~top) / 2) + clRect~top + + clRect1 = .Rect~new(clRect~left, clRect~top, hMidpoint, vMidpoint) + clRect2 = .Rect~new(hMidpoint + 1, clRect~top, clRect~right, vMidpoint + 1) + clRect3 = .Rect~new(clRect~left, vMidpoint + 1, hMidpoint + 1, clRect~bottom) + clRect4 = .Rect~new(hMidpoint + 1, vMidpoint + 1, clRect~right, clRect~bottom) + + ret = tt~addToolRect(self, IDTOOL_DLG_RECT1, clRect1, 'Over main dialog, top left quadrant', 'TRANSPARENT') + ret = tt~addToolRect(self, IDTOOL_DLG_RECT2, clRect2, 'Over main dialog, top right quadrant', 'TRANSPARENT') + ret = tt~addToolRect(self, IDTOOL_DLG_RECT3, clRect3, 'Over main dialog, bottom left quadrant', 'TRANSPARENT') + ret = tt~addToolRect(self, IDTOOL_DLG_RECT4, clRect4, 'Over main dialog, bottom right quadrant', 'TRANSPARENT') + + -- Connect the SHOW event so that we can position the tool tip text where + -- we want it. The SHOW notification is sent right before the tool tip is + -- going to display its window. + self~connectToolTipEvent(IDC_TT_MAIN, 'SHOW') + + +/** onShow() + * + * This is the event handler for the ToolTip SHOW event. It is invoked right + * before the ToolTip is about to show its display window. + * + * One of the uses for this event is to customize the position of the window. + * To customize the window position, the programmer calculates where he wants + * the window to be position and then uses the setWindowPos() method to place + * the window. When the position is set by the programmer, the event handler + * needs to return .true to inform the ToolTip not to position the window in its + * default position. If .false is returned, then the ToolTip positions its + * window where it normally would. + * + * We use this event handler to place the text for each tool in the main ToolTip + * at the top left-hand corner of its rectangle. + */ +::method onShow unguarded + expose clRect1 clRect2 clRect3 clRect4 + use arg toolID, toolTip + + -- Determine the position for the tool about to be displayed: + select + when toolID == .constDir[IDTOOL_DLG_RECT1] then pos = .Point~new(clRect1~left, clRect1~top) + when toolID == .constDir[IDTOOL_DLG_RECT2] then pos = .Point~new(clRect2~left, clRect2~top) + when toolID == .constDir[IDTOOL_DLG_RECT3] then pos = .Point~new(clRect3~left, clRect3~top) + when toolID == .constDir[IDTOOL_DLG_RECT4] then pos = .Point~new(clRect4~left, clRect4~top) + otherwise pos = .Point~new + end + -- End select + + -- Position the ToolTip window where we want it: + self~client2screen(pos) + toolTip~setWindowPos(TOPMOST, pos, .Size~new(0, 0), "NOACTIVATE NOSIZE NOZORDER") + + -- Return .true so that the ToolTip knows not to position the window itself. + return .true + + +/** onNeedText() + * + * This is the event handler for the ToolTip NEEDTEXT event. It is invoked when + * a ToolTip control needs the text to display in its window. + * + * The notification is generated when there is no text assigned to a tool, of if + * the special string: "TextCallBack" is assigned as the text of a tool. + * + * The event handler must return .true or .false. It .true is returned, that + * tells the ToolTip to store the returned text and not ask for it again. If + * .false is returned, then the ToolTip will ask for the text each time the + * window is about to be displayed. + * + * The text itself is returned in the info object. This is a .Directory object. + * The returned text is placed at the TEXT index. + */ +::method onNeedText unguarded + use arg id, toolTip, info + + info~text = 'Press Test to execute a ToolTip test' + return .true + + +/** onTest() + * + * This is the event handler for the button CLICK event. It is invoked when the + * 'Test' push button is pressed or clicked. + * + * We use this to demonstrate some of the methods of the ToolTip class. + */ +::method onTest unguarded + expose tt ttTest pbTest count + + reply 0 + count += 1 + + select + when count == 1 then do + do i = 1 to tt~getToolCount + toolInfo = tt~enumTools(i) + say 'Tool info hwnd: ' toolInfo~rexxHwnd + say 'Tool info id: ' toolInfo~rexxID + say 'Tool info text: ' toolInfo~text + say 'Tool info flags: ' toolInfo~flags + say 'Tool info rect: ' toolInfo~rect + say 'Tool info userData:' toolInfo~userData + say 'Tool info resource:' toolInfo~resource + say + end + end + + when count == 2 then do + time = tt~getDelayTime + say 'Time for autopop:' time + say + + time = tt~getDelayTime('AUTOPOP') + say 'Time for autopop:' time + say + + time = tt~getDelayTime('INITIAL') + say 'Time for initial:' time + say + + time = tt~getDelayTime('RESHOW') + say 'Time for reshow:' time + say + end + + when count == 3 then do + mouse = .Mouse~new(self) + pos = mouse~getCursorPos + pbTest~screen2client(pos) + + hitTool = .ToolInfo~forHitTest(pbTest) + + if ttTest~hitTest(hitTool, pos) then do + say 'Got hit' + say 'Tool info hwnd: ' hitTool~rexxHwnd + say 'Tool info id: ' hitTool~rexxID + say 'Tool info text: ' hitTool~text + say 'Tool info flags: ' hitTool~flags + say 'Tool info rect: ' hitTool~rect + say 'Tool info userData:' hitTool~userData + say 'Tool info resource:' hitTool~resource + say + end + else do + say 'NO hit' + say 'Tool info hwnd: ' hitTool~rexxHwnd~hwnd + say 'Test push button hwnd:' pbTest~hwnd + say + end + end + + otherwise do + count = 0 + say 'No test for this push. Going to recycle.' + say + end + end + -- End select + + return + Added: ooDialog/trunk/examples/controls/musicNote.ico =================================================================== (Binary files differ) Property changes on: ooDialog/trunk/examples/controls/musicNote.ico ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Deleted: ooDialog/trunk/examples/controls/toolTip.rex =================================================================== --- ooDialog/trunk/examples/controls/toolTip.rex 2012-11-28 04:10:32 UTC (rev 8636) +++ ooDialog/trunk/examples/controls/toolTip.rex 2012-11-29 00:41:15 UTC (rev 8637) @@ -1,145 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* */ -/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ -/* */ -/* This program and the accompanying materials are made available under */ -/* the terms of the Common Public License v1.0 which accompanies this */ -/* distribution. A copy is also available at the following address: */ -/* http://www.oorexx.org/license.html */ -/* */ -/* Redistribution and use in source and binary forms, with or */ -/* without modification, are permitted provided that the following */ -/* conditions are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* Redistributions in binary form must reproduce the above copyright */ -/* notice, this list of conditions and the following disclaimer in */ -/* the documentation and/or other materials provided with the distribution. */ -/* */ -/* Neither the name of Rexx Language Association... [truncated message content] |
From: <mie...@us...> - 2012-11-29 22:36:10
|
Revision: 8642 http://sourceforge.net/p/oorexx/code-0/8642 Author: miesfeld Date: 2012-11-29 22:36:06 +0000 (Thu, 29 Nov 2012) Log Message: ----------- ooDialog - fix some details for a 4.2.1 release Modified Paths: -------------- ooDialog/trunk/examples/treeViewCustomDraw.rex ooDialog/trunk/install/ooDialog.nsi ooDialog/trunk/ooDialog/ListView.cls ooDialog/trunk/ooDialog/TreeView.cls ooDialog/trunk/ooDialog/oodListView.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp ooDialog/trunk/ooDialog/oodToolTip.cpp ooDialog/trunk/ooDialog/oodTreeView.cpp Added Paths: ----------- ooDialog/trunk/examples/controls/ToolTip/musicNote.ico Removed Paths: ------------- ooDialog/trunk/examples/controls/musicNote.ico Copied: ooDialog/trunk/examples/controls/ToolTip/musicNote.ico (from rev 8640, ooDialog/trunk/examples/controls/musicNote.ico) =================================================================== (Binary files differ) Deleted: ooDialog/trunk/examples/controls/musicNote.ico =================================================================== (Binary files differ) Modified: ooDialog/trunk/examples/treeViewCustomDraw.rex =================================================================== --- ooDialog/trunk/examples/treeViewCustomDraw.rex 2012-11-29 22:35:29 UTC (rev 8641) +++ ooDialog/trunk/examples/treeViewCustomDraw.rex 2012-11-29 22:36:06 UTC (rev 8642) @@ -362,15 +362,15 @@ * tree-view wants the text to display in the info tip. * * If we return the empty string, then no info tip is displayed. Otherwise, the - * text returned is displayed. Here, we only return text when the userData is + * text returned is displayed. Here, we only return text when the itemData is * the string: '...' In that case we return some text. In all other cases we * return the empty string and no info tip is displayed. */ ::method onGetInfoTip unguarded expose tv - use arg id, hItem, text, maxLen, userData + use arg id, hItem, text, maxLen, itemData - if userData == '...' then return 'There are too many books to list' + if itemData == '...' then return 'There are too many books to list' else return '' Modified: ooDialog/trunk/install/ooDialog.nsi =================================================================== --- ooDialog/trunk/install/ooDialog.nsi 2012-11-29 22:35:29 UTC (rev 8641) +++ ooDialog/trunk/install/ooDialog.nsi 2012-11-29 22:36:06 UTC (rev 8642) @@ -201,6 +201,7 @@ File "${ExamplesDir}\controls\ToolTip\*.rex" File "${ExamplesDir}\controls\ToolTip\*.rc" File "${ExamplesDir}\controls\ToolTip\*.h" + File "${ExamplesDir}\controls\ToolTip\*.ico" ; Set the installation directory: SetOutPath $INSTDIR\samples\oodialog\examples Modified: ooDialog/trunk/ooDialog/ListView.cls =================================================================== --- ooDialog/trunk/ooDialog/ListView.cls 2012-11-29 22:35:29 UTC (rev 8641) +++ ooDialog/trunk/ooDialog/ListView.cls 2012-11-29 22:36:06 UTC (rev 8642) @@ -156,8 +156,8 @@ ::method getItemData unguarded external "LIBRARY oodialog lv_getItemData" ::method getItemInfo unguarded external "LIBRARY oodialog lv_getItemInfo" ::method getItemPos unguarded external "LIBRARY oodialog lv_getItemPos" +::method getSubitem unguarded external "LIBRARY oodialog lv_getSubitem" ::method getToolTips unguarded external "LIBRARY oodialog generic_getToolTips" -::method getSubitem unguarded external "LIBRARY oodialog lv_getSubitem" ::method hasCheckBoxes unguarded external "LIBRARY oodialog lv_hasCheckBoxes" ::method hitTestInfo unguarded external "LIBRARY oodialog lv_hitTestInfo" ::method insert unguarded external "LIBRARY oodialog lv_insert" @@ -283,7 +283,7 @@ -- DEPRECATED -::method removeImages unguarded +::method removeImages unguarded -- DEPRECATED return self~removeImageList(.nil, 0) -- DEPRECATED @@ -305,6 +305,23 @@ -- DEPRECATED ::method subclassEdit + +::class 'LvCustomDrawSimple' public +::method init class external "LIBRARY oodialog lvcds_init_cls" +::method init external "LIBRARY oodialog lvcds_init" + +::attribute clrText set external "LIBRARY oodialog lvcds_setClrText" +::attribute clrTextBk set external "LIBRARY oodialog lvcds_setClrTextBk" +::attribute drawStage get external "LIBRARY oodialog lvcds_getDrawStage" +::attribute font set external "LIBRARY oodialog lvcds_setFont" +::attribute id get external "LIBRARY oodialog lvcds_getID" +::attribute item get external "LIBRARY oodialog lvcds_getItem" +::attribute itemData get external "LIBRARY oodialog lvcds_getItemData" +::attribute reply set external "LIBRARY oodialog lvcds_setReply" +::attribute subItem get external "LIBRARY oodialog lvcds_getSubItem" + + + ::class 'LvItem' public -- Do not document for 4.2.0 ::method init external "LIBRARY oodialog lvi_init" ::method unInit external "LIBRARY oodialog lvi_unInit" @@ -337,6 +354,17 @@ ::attribute text set external "LIBRARY oodialog lvi_setText" +::class 'LvFullRow' public -- Do not document for 4.2.0 +::method init external "LIBRARY oodialog lvfr_init" +::method unInit external "LIBRARY oodialog lvfr_unInit" + +::method addSubItem external "LIBRARY oodialog lvfr_addSubitem" +::method item external "LIBRARY oodialog lvfr_item" +::method removeSubItem external "LIBRARY oodialog lvfr_removeSubitem" +::method subItem external "LIBRARY oodialog lvfr_subitem" +::method subItems external "LIBRARY oodialog lvfr_subitems" + + ::class 'LvSubItem' public -- Do not document for 4.2.0 ::method init external "LIBRARY oodialog lvsi_init" ::method unInit external "LIBRARY oodialog lvsi_unInit" @@ -353,29 +381,3 @@ ::attribute text set external "LIBRARY oodialog lvsi_setText" -::class 'LvFullRow' public -- Do not document for 4.2.0 -::method init external "LIBRARY oodialog lvfr_init" -::method unInit external "LIBRARY oodialog lvfr_unInit" - -::method addSubItem external "LIBRARY oodialog lvfr_addSubitem" -::method item external "LIBRARY oodialog lvfr_item" -::method removeSubItem external "LIBRARY oodialog lvfr_removeSubitem" -::method subItem external "LIBRARY oodialog lvfr_subitem" -::method subItems external "LIBRARY oodialog lvfr_subitems" - - -::class 'LvCustomDrawSimple' public -::method init class external "LIBRARY oodialog lvcds_init_cls" -::method init external "LIBRARY oodialog lvcds_init" - -::attribute clrText set external "LIBRARY oodialog lvcds_setClrText" -::attribute clrTextBk set external "LIBRARY oodialog lvcds_setClrTextBk" -::attribute drawStage get external "LIBRARY oodialog lvcds_getDrawStage" -::attribute font set external "LIBRARY oodialog lvcds_setFont" -::attribute id get external "LIBRARY oodialog lvcds_getID" -::attribute item get external "LIBRARY oodialog lvcds_getItem" -::attribute reply set external "LIBRARY oodialog lvcds_setReply" -::attribute subItem get external "LIBRARY oodialog lvcds_getSubItem" -::attribute userData get external "LIBRARY oodialog lvcds_getUserData" - - Modified: ooDialog/trunk/ooDialog/TreeView.cls =================================================================== --- ooDialog/trunk/ooDialog/TreeView.cls 2012-11-29 22:35:29 UTC (rev 8641) +++ ooDialog/trunk/ooDialog/TreeView.cls 2012-11-29 22:36:06 UTC (rev 8642) @@ -72,14 +72,14 @@ if arg(i + 2, 'E') then selImage = arg(i + 2); else selImage = image if arg(i + 3, 'E') then opts = arg(i + 3); else opts = "" if arg(i + 4, 'E') then children = arg(i + 4); else children = 0 - if arg(i + 5, 'E') then userData = arg(i + 5); else userData = .nil + if arg(i + 5, 'E') then itemData = arg(i + 5); else itemData = .nil if i = 1 then do - self~rootArray[i] = self~insert("ROOT", , arg(i), image, selimage, opts~translate, children, userData) + self~rootArray[i] = self~insert("ROOT", , arg(i), image, selimage, opts~translate, children, itemData) return self~rootArray[i] end else if self~rootArray~hasIndex(i - 1) then do if i = 1 then parent = "ROOT"; else parent = self~rootArray[i - 1] - self~rootArray[i] = self~insert(parent, , arg(i), image, selimage, opts~translate, children, userData) + self~rootArray[i] = self~insert(parent, , arg(i), image, selimage, opts~translate, children, itemData) return self~rootArray[i] end else return 0 @@ -159,7 +159,7 @@ if hItem = hNewParent | hNewParent = self~parent(hItem) | self~isAncestor(hItem, hNewParent) then return 0 iinfo. = self~itemInfo(hItem) newRoot = self~insert(hNewParent, , iinfo.!Text, iinfo.!Image, iinfo.!SelectedImage, iinfo.!State, iinfo.!Children, - - iinfo.!userData) + iinfo.!itemData) if iinfo.!Children = 1 then do child = self~child(hItem) @@ -232,6 +232,6 @@ ::attribute font set external "LIBRARY oodialog tvcds_setFont" ::attribute id get external "LIBRARY oodialog tvcds_getID" ::attribute item get external "LIBRARY oodialog tvcds_getItem" +::attribute itemData get external "LIBRARY oodialog tvcds_getItemData" ::attribute reply set external "LIBRARY oodialog tvcds_setReply" ::attribute level get external "LIBRARY oodialog tvcds_getLevel" -::attribute userData get external "LIBRARY oodialog tvcds_getUserData" -- Do not document yet, no way to set user data for tree view Modified: ooDialog/trunk/ooDialog/oodListView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodListView.cpp 2012-11-29 22:35:29 UTC (rev 8641) +++ ooDialog/trunk/ooDialog/oodListView.cpp 2012-11-29 22:36:06 UTC (rev 8642) @@ -3790,7 +3790,7 @@ * indicate the item does not have an icon in the image * list. * - * @param userData [optional] The list-view control can store a single + * @param itemData [optional] The list-view control can store a single * user value with each list-view item. The Rexx * programmer can use this feature to store any single Rexx * object with each list-view item. @@ -3843,7 +3843,7 @@ * valid. */ RexxMethod10(RexxObjectPtr, lvi_init, OPTIONAL_RexxObjectPtr, _index, OPTIONAL_CSTRING, text, - OPTIONAL_int32_t, imageIndex, OPTIONAL_RexxObjectPtr, userData, OPTIONAL_CSTRING, mask, + OPTIONAL_int32_t, imageIndex, OPTIONAL_RexxObjectPtr, itemData, OPTIONAL_CSTRING, mask, OPTIONAL_CSTRING, itemState, OPTIONAL_CSTRING, itemStateMask, OPTIONAL_uint32_t, indent, OPTIONAL_int32_t, groupID, OPTIONAL_RexxArrayObject, columns) { @@ -3899,7 +3899,7 @@ if ( argumentExists(4) ) { - setLviUserData(context, lvi, userData); + setLviUserData(context, lvi, itemData); } if ( argumentExists(5) ) @@ -4036,6 +4036,17 @@ return NULLOBJECT; } +/** LvItem::itemData [attribute] + */ +RexxMethod1(RexxObjectPtr, lvi_itemData, CSELF, pLVI) +{ + return getLviUserData((LPLVITEM)pLVI); +} +RexxMethod2(RexxObjectPtr, lvi_setItemData, RexxObjectPtr, userData, CSELF, pLVI) +{ + return setLviUserData(context, (LPLVITEM)pLVI, userData); +} + /** LvItem::itemState [attribute] */ RexxMethod1(RexxStringObject, lvi_itemState, CSELF, pLVI) @@ -4111,18 +4122,7 @@ return NULLOBJECT; } -/** LvItem::itemData [attribute] - */ -RexxMethod1(RexxObjectPtr, lvi_itemData, CSELF, pLVI) -{ - return getLviUserData((LPLVITEM)pLVI); -} -RexxMethod2(RexxObjectPtr, lvi_setItemData, RexxObjectPtr, userData, CSELF, pLVI) -{ - return setLviUserData(context, (LPLVITEM)pLVI, userData); -} - /** * Methods for the .LvSubItem class. */ @@ -4849,6 +4849,13 @@ return ((pCLvCustomDrawSimple)pCSelf)->item; } +/** LvCustomDrawSimple::itemData [attribute] + */ +RexxMethod1(RexxObjectPtr, lvcds_getItemData, CSELF, pCSelf) +{ + return ((pCLvCustomDrawSimple)pCSelf)->userData; +} + /** LvCustomDrawSimple::reply [attribute] */ RexxMethod2(RexxObjectPtr, lvcds_setReply, uint32_t, reply, CSELF, pCSelf) @@ -4864,11 +4871,4 @@ return ((pCLvCustomDrawSimple)pCSelf)->subItem; } -/** LvCustomDrawSimple::userData [attribute] - */ -RexxMethod1(RexxObjectPtr, lvcds_getUserData, CSELF, pCSelf) -{ - return ((pCLvCustomDrawSimple)pCSelf)->userData; -} - Modified: ooDialog/trunk/ooDialog/oodPackageEntry.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-11-29 22:35:29 UTC (rev 8641) +++ ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-11-29 22:36:06 UTC (rev 8642) @@ -1420,9 +1420,9 @@ REXX_METHOD_PROTOTYPE(lvcds_setFont ); REXX_METHOD_PROTOTYPE(lvcds_getID ); REXX_METHOD_PROTOTYPE(lvcds_getItem ); +REXX_METHOD_PROTOTYPE(lvcds_getItemData ); REXX_METHOD_PROTOTYPE(lvcds_setReply ); REXX_METHOD_PROTOTYPE(lvcds_getSubItem ); -REXX_METHOD_PROTOTYPE(lvcds_getUserData ); // TvCustomDrawSimple REXX_METHOD_PROTOTYPE(tvcds_init_cls ); @@ -1433,9 +1433,9 @@ REXX_METHOD_PROTOTYPE(tvcds_setFont ); REXX_METHOD_PROTOTYPE(tvcds_getID ); REXX_METHOD_PROTOTYPE(tvcds_getItem ); +REXX_METHOD_PROTOTYPE(tvcds_getItemData ); REXX_METHOD_PROTOTYPE(tvcds_setReply ); REXX_METHOD_PROTOTYPE(tvcds_getLevel ); -REXX_METHOD_PROTOTYPE(tvcds_getUserData ); RexxMethodEntry oodialog_methods[] = { @@ -2439,10 +2439,10 @@ REXX_METHOD(lvcds_getDrawStage, lvcds_getDrawStage), REXX_METHOD(lvcds_setFont, lvcds_setFont), REXX_METHOD(lvcds_getItem, lvcds_getItem), + REXX_METHOD(lvcds_getItemData, lvcds_getItemData), REXX_METHOD(lvcds_getID, lvcds_getID), REXX_METHOD(lvcds_setReply, lvcds_setReply), REXX_METHOD(lvcds_getSubItem, lvcds_getSubItem), - REXX_METHOD(lvcds_getUserData, lvcds_getUserData), // TvCustomDrawSimple REXX_METHOD(tvcds_init_cls, tvcds_init_cls), @@ -2453,9 +2453,9 @@ REXX_METHOD(tvcds_setFont, tvcds_setFont), REXX_METHOD(tvcds_getID, tvcds_getID), REXX_METHOD(tvcds_getItem, tvcds_getItem), + REXX_METHOD(tvcds_getItemData, tvcds_getItemData), REXX_METHOD(tvcds_setReply, tvcds_setReply), REXX_METHOD(tvcds_getLevel, tvcds_getLevel), - REXX_METHOD(tvcds_getUserData, tvcds_getUserData), REXX_LAST_METHOD() }; Modified: ooDialog/trunk/ooDialog/oodToolTip.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodToolTip.cpp 2012-11-29 22:35:29 UTC (rev 8641) +++ ooDialog/trunk/ooDialog/oodToolTip.cpp 2012-11-29 22:36:06 UTC (rev 8642) @@ -527,7 +527,7 @@ * hwndSupplier and uIDSupplier. */ static bool genericToolID(RexxMethodContext *c, RexxObjectPtr rxObj, RexxObjectPtr rxID, LPTOOLINFO pTI, - RexxObjectPtr *hwndSupplier, RexxObjectPtr *uIDSupplier) + RexxObjectPtr *hwndSupplier, RexxObjectPtr *uIDSupplier, size_t arg1Pos) { bool success = false; @@ -544,7 +544,7 @@ if ( rxID == NULLOBJECT ) { - if ( ! requiredClass(c->threadContext, rxObj, "DIALOGCONTROL", 1) ) + if ( ! requiredClass(c->threadContext, rxObj, "DIALOGCONTROL", arg1Pos) ) { goto done_out; } @@ -584,7 +584,7 @@ } else { - uint32_t id = oodResolveSymbolicID(c->threadContext, pcpbd->rexxSelf, rxID, -1, 2, false); + uint32_t id = oodResolveSymbolicID(c->threadContext, pcpbd->rexxSelf, rxID, -1, arg1Pos + 1, false); if ( id == OOD_ID_EXCEPTION ) { goto done_out; @@ -604,7 +604,7 @@ { pCDialogControl pcdc = controlToCSelf(c, rxObj); - uint32_t id = oodResolveSymbolicID(c->threadContext, pcdc->oDlg, rxID, -1, 2, false); + uint32_t id = oodResolveSymbolicID(c->threadContext, pcdc->oDlg, rxID, -1, arg1Pos + 1, false); if ( id == OOD_ID_EXCEPTION ) { goto done_out; @@ -1533,7 +1533,7 @@ goto done_out; } - if ( ! genericToolID(context, toolID, uID, &ti, NULL, NULL) ) + if ( ! genericToolID(context, toolID, uID, &ti, NULL, NULL, 1) ) { goto done_out; } @@ -1632,7 +1632,7 @@ { pTI = (LPTOOLINFO)context->ObjectToCSelf(toolHwnd); } - else if ( ! genericToolID(context, toolHwnd, toolID, pTI, NULL, NULL) ) + else if ( ! genericToolID(context, toolHwnd, toolID, pTI, NULL, NULL, 1) ) { goto done_out; } @@ -1835,7 +1835,7 @@ goto done_out; } - if ( ! genericToolID(context, toolID, uID, &ti, NULL, NULL) ) + if ( ! genericToolID(context, toolID, uID, &ti, NULL, NULL, 1) ) { goto done_out; } @@ -2044,7 +2044,7 @@ goto done_out; } - if ( ! genericToolID(context, toolHwnd, toolID, pTI, NULL, NULL) ) + if ( ! genericToolID(context, toolHwnd, toolID, pTI, NULL, NULL, 1) ) { goto done_out; } @@ -2375,19 +2375,19 @@ * * Sets a new bounding rectangle for a tool. * + * @param rect [required] The new bounding rectangle for the tool. + * * @param toolHwnd [required] * * @param toolID [optional] * - * @param rect [required] The new bounding rectangle for the tool. - * * @return Returns 0 always. * * @notes toolHwnd and toolId are the Rexx object combination that uniquely * specifies a tool to this tool tip. * */ -RexxMethod4(uint32_t, tt_newToolRect, RexxObjectPtr, toolID, OPTIONAL_RexxObjectPtr, uID, RexxObjectPtr, r, CSELF, pCSelf) +RexxMethod4(uint32_t, tt_newToolRect, RexxObjectPtr, r, RexxObjectPtr, toolID, OPTIONAL_RexxObjectPtr, uID, CSELF, pCSelf) { TOOLINFO ti = { sizeof(ti) }; @@ -2397,12 +2397,12 @@ goto done_out; } - if ( ! genericToolID(context, toolID, uID, &ti, NULL, NULL) ) + if ( ! genericToolID(context, toolID, uID, &ti, NULL, NULL, 2) ) { goto done_out; } - PRECT pRect = rxGetRect(context, r, 3); + PRECT pRect = rxGetRect(context, r, 1); if ( pRect == NULL ) { goto done_out; @@ -2847,7 +2847,7 @@ goto done_out; } - if ( ! genericToolID(context, toolHwnd, toolID, &ti, NULL, NULL) ) + if ( ! genericToolID(context, toolHwnd, toolID, &ti, NULL, NULL, 1) ) { goto done_out; } @@ -3076,7 +3076,7 @@ RexxObjectPtr hwndSupplier; RexxObjectPtr uIDSupplier; - if ( ! genericToolID(context, hwndObj, rxID, pTI, &hwndSupplier, &uIDSupplier) ) + if ( ! genericToolID(context, hwndObj, rxID, pTI, &hwndSupplier, &uIDSupplier, 1) ) { goto done_out; } @@ -3182,7 +3182,7 @@ RexxObjectPtr hwndSupplier; RexxObjectPtr uIDSupplier; - if ( ! genericToolID(context, hwndObj, rxID, pTI, &hwndSupplier, &uIDSupplier) ) + if ( ! genericToolID(context, hwndObj, rxID, pTI, &hwndSupplier, &uIDSupplier, 1) ) { goto done_out; } Modified: ooDialog/trunk/ooDialog/oodTreeView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodTreeView.cpp 2012-11-29 22:35:29 UTC (rev 8641) +++ ooDialog/trunk/ooDialog/oodTreeView.cpp 2012-11-29 22:36:06 UTC (rev 8642) @@ -1371,7 +1371,7 @@ } context->SetStemElement(stem, "!STATE", context->String(buf)); - context->SetStemElement(stem, "!USERDATA", tvi.lParam ? (RexxObjectPtr)tvi.lParam : TheNilObj); + context->SetStemElement(stem, "!ITEMDATA", tvi.lParam ? (RexxObjectPtr)tvi.lParam : TheNilObj); return stem; } @@ -2254,6 +2254,14 @@ return pointer2string(context, ((pCTvCustomDrawSimple)pCSelf)->item); } +/** TvCustomDrawSimple::itemData [attribute] + */ +RexxMethod1(RexxObjectPtr, tvcds_getItemData, CSELF, pCSelf) +{ + RexxObjectPtr data = (RexxObjectPtr)((pCTvCustomDrawSimple)pCSelf)->userData; + return data == NULLOBJECT ? TheNilObj : data; +} + /** TvCustomDrawSimple::reply [attribute] */ RexxMethod2(RexxObjectPtr, tvcds_setReply, uint32_t, reply, CSELF, pCSelf) @@ -2269,12 +2277,4 @@ return ((pCTvCustomDrawSimple)pCSelf)->level + 1; } -/** TvCustomDrawSimple::userData [attribute] - */ -RexxMethod1(RexxObjectPtr, tvcds_getUserData, CSELF, pCSelf) -{ - RexxObjectPtr data = (RexxObjectPtr)((pCTvCustomDrawSimple)pCSelf)->userData; - return data == NULLOBJECT ? TheNilObj : data; -} - |
From: <mie...@us...> - 2012-12-01 20:19:27
|
Revision: 8650 http://sourceforge.net/p/oorexx/code-0/8650 Author: miesfeld Date: 2012-12-01 20:19:24 +0000 (Sat, 01 Dec 2012) Log Message: ----------- Fix bug: #1146 Return code from ListView::deleteColumn() not as documented See ticket [Bugs:#1146] Work on RFE: #478 ooDialog - List-view could use a way to work with a complete row See ticket [Feature-Requests:#478] Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/ooDialog/ListView.cls ooDialog/trunk/ooDialog/oodListView.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-01 05:51:19 UTC (rev 8649) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-01 20:19:24 UTC (rev 8650) @@ -84,7 +84,10 @@ * #1141 ooDialog - connecting system menu command events can fail +* #1145 TimedMessage dialog remains on screen after ok() method is + invoked + Feature Requests in ooDialog: ----------------------------- Modified: ooDialog/trunk/ooDialog/ListView.cls =================================================================== --- ooDialog/trunk/ooDialog/ListView.cls 2012-12-01 05:51:19 UTC (rev 8649) +++ ooDialog/trunk/ooDialog/ListView.cls 2012-12-01 20:19:24 UTC (rev 8650) @@ -111,10 +111,7 @@ ::method delete unguarded external "LIBRARY oodialog lv_delete" ::method deleteAll unguarded external "LIBRARY oodialog lv_deleteAll" -::method deleteColumn unguarded - use strict arg index - return self~sendWinIntMsg(self~LVM_DELETECOLUMN, index, 0) <> 0 - +::method deleteColumn unguarded external "LIBRARY oodialog lv_deleteColumn" ::method deselect unguarded external "LIBRARY oodialog lv_setSpecificState" ::method deselectAll unguarded external "LIBRARY oodialog lv_deselectAll" ::method dropHighlighted unguarded external "LIBRARY oodialog lv_getNextItemWithState" @@ -322,7 +319,13 @@ -::class 'LvItem' public -- Do not document for 4.2.0 +::class 'LvItem' public + +::constant GROUPIDCALLBACK -1 +::constant GROUPIDNONE -2 +::constant IMAGECALLBACK -1 +::constant IMAGENONE -2 + ::method init external "LIBRARY oodialog lvi_init" ::method unInit external "LIBRARY oodialog lvi_unInit" Modified: ooDialog/trunk/ooDialog/oodListView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-01 05:51:19 UTC (rev 8649) +++ ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-01 20:19:24 UTC (rev 8650) @@ -59,6 +59,8 @@ #define LVSTATE_ATTRIBUTE "LV!STATEIMAGELIST" #define LVSMALL_ATTRIBUTE "LV!SMALLIMAGELIST" #define LVNORMAL_ATTRIBUTE "LV!NORMALIMAGELIST" + +#define LVITEM_ALL_MASK LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE | LVIF_INDENT | LVIF_COLUMNS | LVIF_COLFMT | LVIF_GROUPID | LVIF_NORECOMPUTE #define LVITEM_TEXT_MAX 260 #define LVITEM_TILECOLUMN_MAX 20 // According to MSDN @@ -307,6 +309,188 @@ } /** + * Allocates memory for the text buffer in a list-view item structure. + * + * This should only be used for Rexx objects such as a LvItem or LvSubItem, + * etc., where the uninit method of the object will free the buffer. + * + * @param c + * @param pLVI + * + * @return True on success, false on memory allocation failure. + */ +static bool allocLviTextBuf(RexxMethodContext *c, LPLVITEM pLVI) +{ + char *pszText = (char *)LocalAlloc(LPTR, LVITEM_TEXT_MAX + 1); + if ( pszText == NULL ) + { + outOfMemoryException(c->threadContext); + return false; + } + + safeLocalFree(pLVI->pszText); + pLVI->pszText = pszText; + + pLVI->cchTextMax = (LVITEM_TEXT_MAX + 1); + return true; +} + +/** + * Allocates a buffer for the LISTITEM.puColumns field to recieve data. The + * buffer is set big enough for the maximum number of columns. + * + * @param c + * @param pLVI + * + * @return bool + */ +static bool allocLviColumns(RexxMethodContext *c, LPLVITEM pLVI) +{ + uint32_t *puColumns = (uint32_t *)LocalAlloc(LPTR, LVITEM_TILECOLUMN_MAX * sizeof(uint32_t *)); + if ( puColumns == NULL ) + { + outOfMemoryException(c->threadContext); + return false; + } + + safeLocalFree(pLVI->puColumns); + pLVI->puColumns = puColumns; + pLVI->cColumns = LVITEM_TILECOLUMN_MAX; + + return true; +} + +/** + * Allocates a buffer for the LISTITEM.piColFmt field to recieve data. The + * buffer is set big enough for the maximum number of columns. + * + * @param c + * @param pLVI + * + * @return bool + */ +static bool allocLviColFmt(RexxMethodContext *c, LPLVITEM pLVI) +{ + int32_t *piColFmt = (int32_t *)LocalAlloc(LPTR, LVITEM_TILECOLUMN_MAX * sizeof(uint32_t *)); + if ( piColFmt == NULL ) + { + outOfMemoryException(c->threadContext); + return false; + } + + safeLocalFree(pLVI->piColFmt); + pLVI->piColFmt = piColFmt; + pLVI->cColumns = LVITEM_TILECOLUMN_MAX; + + return true; +} + +/** + * Allocates memory for the tile column buffers in a list-view item structure. + * + * This should only be used for the LvItem Rexx objects, where the uninit method + * of the object will free the buffers. + * + * @param c + * @param pLVI + * + * @return True on success, false on memory allocation failure. + * + * @remarks If possible, we don't want to change the existing LVITEM struct + * until we are sure things succeed. + */ +static bool allocLviTileCols(RexxMethodContext *c, LPLVITEM pLVI) +{ + uint32_t *puColumns = (uint32_t *)LocalAlloc(LPTR, LVITEM_TILECOLUMN_MAX * sizeof(uint32_t *)); + if ( puColumns == NULL ) + { + outOfMemoryException(c->threadContext); + return false; + } + + int32_t *piColFmt = (int32_t *)LocalAlloc(LPTR, LVITEM_TILECOLUMN_MAX * sizeof(uint32_t *)); + if ( piColFmt == NULL ) + { + safeLocalFree(puColumns); + outOfMemoryException(c->threadContext); + return false; + } + + safeLocalFree(pLVI->puColumns); + pLVI->puColumns = puColumns; + + safeLocalFree(pLVI->piColFmt); + pLVI->piColFmt = piColFmt; + + pLVI->cColumns = LVITEM_TILECOLUMN_MAX; + + return true; +} + +/** + * Ensures that the buffers in a LVITEM structure are allocated to recieve + * information. + * + * @param c + * @param pLVI + * + * @return bool + * + * @remarks There is a vague assumption here that the LVITEM struct is only + * going to be used for a ListView_GetItem() call. For a + * ListView_SetItem() call, the buffers would have been allocated as + * the Rexx object attributes were set. + * + * However, this is also called when an LvItem in a LvFullRow is going + * to be updated. It doesn't seem like having a too big buffer should + * be a problem ... + * + * We don't want to change anything in the existing LVITEM struct, if + * at all possible. So rather than call allocLviTextBuf() and + * allocLvitTileCols() individually, we duplicate their code here. + */ +static bool ensureLvItemBuffers(RexxMethodContext *c, LPLVITEM pLVI) +{ + char *pszText = (char *)LocalAlloc(LPTR, LVITEM_TEXT_MAX + 1); + if ( pszText == NULL ) + { + outOfMemoryException(c->threadContext); + return false; + } + + uint32_t *puColumns = (uint32_t *)LocalAlloc(LPTR, LVITEM_TILECOLUMN_MAX * sizeof(uint32_t *)); + if ( puColumns == NULL ) + { + safeLocalFree(pszText); + outOfMemoryException(c->threadContext); + return false; + } + + int32_t *piColFmt = (int32_t *)LocalAlloc(LPTR, LVITEM_TILECOLUMN_MAX * sizeof(uint32_t *)); + if ( piColFmt == NULL ) + { + safeLocalFree(pszText); + safeLocalFree(puColumns); + outOfMemoryException(c->threadContext); + return false; + } + + safeLocalFree(pLVI->pszText); + pLVI->pszText = pszText; + + safeLocalFree(pLVI->puColumns); + pLVI->puColumns = puColumns; + + safeLocalFree(pLVI->piColFmt); + pLVI->piColFmt = piColFmt; + + pLVI->cchTextMax = LVITEM_TEXT_MAX + 1; + pLVI->cColumns = LVITEM_TILECOLUMN_MAX; + + return true; +} + +/** * Uses MapIDToIndex and the unique ID stored with a LvFullRow object to correct * the item index in the LPLVITEM structs within the full row item and subitems * @@ -334,21 +518,44 @@ * @param pclvfr * * @assumes updateFullRowIndexes() has already been invoked. + * + * @remarks Originally, this function just updated the state member of the + * struct. But now it does a fresh ListView_Item() with all flags for + * the mask being set. This should make sure the Rexx LvItem object + * accurately reflects the current state of underlying list-view item. + * + * But, it is changing what the mask value is from what the Rexx user + * may have set. I think this is okay, but it sort of depends on how + * well the list-view implementation follows what the MSDN docs say + * ... + * + * There is one problem with the groupId field of the LVITEM struct. + * If the LVIF_GROUPID flag is set and there is no group ID in the + * item, the OS does not seem to update the groupId field to + * I_GROUPIDNONE (-2). If the LVITEM struct is then used to insert the + * item with LVIF_GROUPID still set and the groupId field set to 0, + * the insert field fails. If the field is already set to -2, things + * are okay. Have not had a chance to test when the field is say 2. + * For now, if the field comes back 0, we change it to I_GROUPID_NONE. */ -static void updateFullRowItemState(pCLvFullRow pclvfr) +static void updateFullRowItemState(RexxMethodContext *c, pCLvFullRow pclvfr) { if ( pclvfr->hList != NULL ) { LPLVITEM pLvi = pclvfr->subItems[0]; - LVITEM lvi = {0}; - lvi.iItem = pLvi->iItem; - lvi.mask = LVIF_STATE; - lvi.stateMask = (uint32_t)-1; + if ( ! ensureLvItemBuffers(c, pLvi) ) + { + return; + } - if ( ListView_GetItem(pclvfr->hList, &lvi) ) + pLvi->mask = LVITEM_ALL_MASK; + pLvi->stateMask = (uint32_t)-1; + + ListView_GetItem(pclvfr->hList, pLvi); + if ( pLvi->iGroupId == 0 ) { - pLvi->state = lvi.state; + pLvi->iGroupId = I_GROUPIDNONE; } } } @@ -396,63 +603,6 @@ } /** - * Allocates memory for the text buffer in a list-view item structure. - * - * This should only be used for Rexx objects such as a LvItem or LvSubItem, - * etc., where the uninit method of the object will free the buffer. - * - * @param c - * @param pLVI - * - * @return True on success, false on memory allocation failure. - */ -static bool allocLviTextBuf(RexxMethodContext *c, LPLVITEM pLVI) -{ - - pLVI->pszText = (char *)LocalAlloc(LPTR, LVITEM_TEXT_MAX + 1); - if ( pLVI->pszText == NULL ) - { - outOfMemoryException(c->threadContext); - return false; - } - - pLVI->cchTextMax = (LVITEM_TEXT_MAX + 1); - return true; -} - -/** - * Allocates memory for the tile column buffers in a list-view item structure. - * - * This should only be used for the LvItem Rexx objects, where the uninit method - * of the object will free the buffers. - * - * @param c - * @param pLVI - * - * @return True on success, false on memory allocation failure. - */ -static bool allocLviTileCols(RexxMethodContext *c, LPLVITEM pLVI) -{ - - pLVI->puColumns = (uint32_t *)LocalAlloc(LPTR, LVITEM_TILECOLUMN_MAX * sizeof(uint32_t *)); - if ( pLVI->puColumns == NULL ) - { - outOfMemoryException(c->threadContext); - return false; - } - - pLVI->piColFmt = (int32_t *)LocalAlloc(LPTR, LVITEM_TILECOLUMN_MAX * sizeof(uint32_t *)); - if ( pLVI->piColFmt == NULL ) - { - safeLocalFree(pLVI->puColumns); - outOfMemoryException(c->threadContext); - return false; - } - - return true; -} - -/** * Each item in a list-view allows the user to store a value at the lParam * member of the LVITEM struct. * @@ -697,6 +847,15 @@ * @param itemIndex * * @return RexxObjectPtr + * + * @remarks Note that the iGroupId field of the LVITEM struct is a little + * hokey. If we set the LVIF_GROUPID flag in the mask to retrieve + * the group ID and there is no group ID, the OS returns 0, instead of + * I_GROUPIDNONE (-2). If we keep the LVIF_GROUPID flag set, and try + * to insert the item with the groupId set to 0, the insert fails. + * + * I don't know if this is because groups are not available or what. + * For new, we check for a 0 value and change it to I_GROUPIDNONE. */ static RexxObjectPtr newLvItem(RexxMethodContext *c, HWND hList, uint32_t itemIndex) { @@ -712,26 +871,23 @@ LPLVITEM lvi = (LPLVITEM)c->BufferData(obj); memset(lvi, 0, sizeof(LVITEM)); - // setLviText() will allocate the buffer for us. - if ( ! allocLviTextBuf(c, lvi) ) + if ( ! ensureLvItemBuffers(c, lvi) ) { goto err_out; } - if ( ! allocLviTileCols(c, lvi) ) - { - goto err_out; - } - lvi->iItem = itemIndex; lvi->stateMask = (uint32_t)-1; - lvi->cColumns = LVITEM_TILECOLUMN_MAX; - lvi->mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE | LVIF_INDENT | LVIF_COLUMNS | LVIF_COLFMT | LVIF_GROUPID; + lvi->mask = LVITEM_ALL_MASK; if ( ! ListView_GetItem(hList, lvi) ) { goto err_out; } + if ( lvi->iGroupId == 0 ) + { + lvi->iGroupId = I_GROUPIDNONE; + } RexxClassObject rxLvI = rxGetContextClass(c, "LVITEM"); if ( rxLvI == NULLOBJECT ) @@ -1510,6 +1666,29 @@ return ListView_DeleteAllItems(pcdc->hCtrl) ? TheZeroObj : TheOneObj; } +/** ListView::deleteColumn() + * + * Delectes the specified column. + * + * @param index [required] The zero-based index of the column to delete + * + * @return 0 on success, 1 on error. + * + * @notes Column 0 can not be deleted. If column 0 must be deleted, MSDN + * suggests inserting a dummy column at index 0 and then deleting + * column 1. + */ +RexxMethod2(RexxObjectPtr, lv_deleteColumn, uint32_t, index, CSELF, pCSelf) +{ + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) + { + return TheOneObj; + } + + return ListView_DeleteColumn(pcdc->hCtrl, index) ? TheZeroObj : TheOneObj; +} + /** ListView::deselectAll() * * @@ -1676,31 +1855,31 @@ HWND hList = getDChCtrl(pCSelf); - LVCOLUMN lvi; + LVCOLUMN lvc; char buf[256]; - lvi.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT | LVCF_WIDTH; - lvi.pszText = buf; - lvi.cchTextMax = 255; + lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT | LVCF_WIDTH; + lvc.pszText = buf; + lvc.cchTextMax = 255; - if ( ! ListView_GetColumn(hList, index, &lvi) ) + if ( ! ListView_GetColumn(hList, index, &lvc) ) { return TheFalseObj; } char *align = "LEFT"; - if ( (LVCFMT_JUSTIFYMASK & lvi.fmt) == LVCFMT_CENTER ) + if ( (LVCFMT_JUSTIFYMASK & lvc.fmt) == LVCFMT_CENTER ) { align = "CENTER"; } - else if ( (LVCFMT_JUSTIFYMASK & lvi.fmt) == LVCFMT_RIGHT ) + else if ( (LVCFMT_JUSTIFYMASK & lvc.fmt) == LVCFMT_RIGHT ) { align = "RIGHT"; } - context->DirectoryPut(d, context->String(lvi.pszText), "TEXT"); - context->DirectoryPut(d, context->Int32(lvi.iSubItem), "SUBITEM"); - context->DirectoryPut(d, context->Int32(lvi.cx), "WIDTH"); + context->DirectoryPut(d, context->String(lvc.pszText), "TEXT"); + context->DirectoryPut(d, context->Int32(lvc.iSubItem), "SUBITEM"); + context->DirectoryPut(d, context->Int32(lvc.cx), "WIDTH"); context->DirectoryPut(d, context->String(align), "FMT"); return TheTrueObj; @@ -1814,6 +1993,7 @@ * maybeGetFullRow() updates the item index in the Rexx objects to * the correct index. But we also need to do * updateFullRowItemState() to be sure and get the current state. + * TODO !!! we also need a updateFullRowSubItemStates(). Maybe ?? * * If there is no LvFullRow object as the user data, the most likely * case, we create the object here. We do that by creating Rexx @@ -1831,7 +2011,7 @@ pCLvFullRow pclvfr = maybeGetFullRow(hList, itemIndex); if ( pclvfr != NULL ) { - updateFullRowItemState(pclvfr); + updateFullRowItemState(context, pclvfr); return pclvfr->rexxSelf; } @@ -1954,22 +2134,49 @@ /** ListView::getItem() * - * Returns a LvItem object for the item specified. + * Returns, or fills in, a LvItem object for the item specified. * + * @param _item [required] Can be a LvItem object or the item index. If it is + * a LvItem, we just fill it in. If it is an index and we have + * no LvFullRow, we return a new, filled in, LvItem object. If + * we do have a LvFullRow, we update the LVITEM struct for the + * item and then return the Rexx LvItem. + * + * @remarks If we have a LvFullRow object assigned to the user data, we use + * the Rexx item in the full row. maybeGetFullRow() will update the item + * index, and then updateFullRowItemState will sync the LVITEM struct by doing + * a fresh ListView_GetItem() which will ensure things are correct. + * */ -RexxMethod2(RexxObjectPtr, lv_getItem, uint32_t, itemIndex, CSELF, pCSelf) +RexxMethod2(RexxObjectPtr, lv_getItem, RexxObjectPtr, _item, CSELF, pCSelf) { RexxObjectPtr result = TheNilObj; HWND hList = getDChCtrl(pCSelf); - // If we have a LvFullRow object assigned to the user data, we use the Rexx - // item in the full row. maybeGetFullRow() will update the item index, - // which will ensure things are correct. + if ( context->IsOfType(_item, "LVITEM") ) + { + LPLVITEM plvi = (LPLVITEM)context->ObjectToCSelf(_item); + BOOL success = ListView_GetItem(hList, plvi); + if ( success && (plvi->mask & LVIF_GROUPID) && plvi->iGroupId ) + { + plvi->iGroupId = I_GROUPIDNONE; + } + + return success ? TheTrueObj : TheFalseObj; + } + + uint32_t itemIndex; + if ( ! context->UnsignedInt32(_item, &itemIndex) ) + { + wrongArgValueException(context->threadContext, 1, "a LvItem object or valid item index", _item); + return TheNilObj; + } + pCLvFullRow pclvfr = maybeGetFullRow(hList, itemIndex); if ( pclvfr != NULL ) { - updateFullRowItemState(pclvfr); + updateFullRowItemState(context, pclvfr); result = pclvfr->rxSubItems[0]; } else @@ -2078,7 +2285,7 @@ { if ( ! subitemImages ) { - lvi.iImage = -1; + lvi.iImage = I_IMAGENONE; } } @@ -3354,14 +3561,23 @@ * @param flags * * @return uint32_t + * + * @remarks The special keyword ALL adds, almose, all flags. LVIF_DI_SETITEM is + * only valid in an event notification, so that should be skipped. I + * am not sure about LVIF_NORECOMPUTE though? Adding it for now. */ uint32_t keyword2lvif(CSTRING flags) { uint32_t val = 0; + if ( StrCmpI(flags, "ALL") == 0 ) + { + val = LVITEM_ALL_MASK; + return val; + } + if ( StrStrI(flags, "COLFMT") != NULL ) val |= LVIF_COLFMT; if ( StrStrI(flags, "COLUMNS") != NULL ) val |= LVIF_COLUMNS; - if ( StrStrI(flags, "DI_SETITEM") != NULL ) val |= LVIF_DI_SETITEM; if ( StrStrI(flags, "GROUPID") != NULL ) val |= LVIF_GROUPID; if ( StrStrI(flags, "IMAGE") != NULL ) val |= LVIF_IMAGE; if ( StrStrI(flags, "INDENT") != NULL ) val |= LVIF_INDENT; @@ -3480,8 +3696,12 @@ return c->String(buf); } -RexxStringObject getLviText(RexxMethodContext *c, LPLVITEM pLVI) +RexxObjectPtr getLviText(RexxMethodContext *c, LPLVITEM pLVI) { + if ( pLVI->pszText == NULL ) + { + return TheNilObj; + } return c->String(pLVI->pszText); } @@ -3547,11 +3767,23 @@ return NULLOBJECT; } +/** + * Gets the group ID of this item. + * + * Note that group IDs are sort of like resource IDs, they are not the index of + * a group. A group at index 3, might have a group ID of 101. All items with a + * group ID of 101 belong to that group at index 3. + * + * @param c + * @param pLVI + * + * @return int32_t + */ int32_t getLviGroupID(RexxMethodContext *c, LPLVITEM pLVI) { if ( ! requiredComCtl32Version(c, "LvItem::groupID", COMCTL32_6_0) ) { - return 0; + return I_GROUPIDNONE; } return pLVI->iGroupId; } @@ -3562,8 +3794,12 @@ { return NULLOBJECT; } + if ( id < I_GROUPIDNONE ) + { + id = I_GROUPIDNONE; + } - pLVI->iGroupId = id < I_GROUPIDNONE ? I_GROUPIDNONE : id; + pLVI->iGroupId = id; pLVI->mask |= LVIF_GROUPID; return NULLOBJECT; @@ -3788,7 +4024,8 @@ * * This attribute can be set to the constant I_IMAGENONE to * indicate the item does not have an icon in the image - * list. + * list. If this argument is omitted, it defaults to + * I_IMAGENONE. * * @param itemData [optional] The list-view control can store a single * user value with each list-view item. The Rexx @@ -3859,6 +4096,19 @@ LPLVITEM lvi = (LPLVITEM)context->BufferData(obj); memset(lvi, 0, sizeof(LVITEM)); + // We check if the user is setting the mask, and what values she sets, + // first. This allows use to allocate the needed buffers if the LvItem + // object is going to be used to retrieve information. + if ( argumentExists(5) ) + { + uint32_t flags = keyword2lvif(mask); + if ( flags == (uint32_t)-1 ) + { + return NULLOBJECT; + } + lvi->mask = flags; + } + if ( argumentExists(1) ) { int32_t index; @@ -3882,36 +4132,34 @@ return NULLOBJECT; } } - else if ( lvi->mask & LVIF_TEXT ) + else { - // The empty string tells setLviText() to allocate a buffer. - if ( ! setLviText(context, lvi, "", 2) ) + // Check if the user has set the LVIF_TEXT flag. + if ( lvi->mask & LVIF_TEXT ) { - return NULLOBJECT; + // The empty string tells setLviText() to allocate a buffer. + if ( ! setLviText(context, lvi, "", 2) ) + { + return NULLOBJECT; + } } } + lvi->mask |= LVIF_IMAGE; if ( argumentExists(3) ) { lvi->iImage = imageIndex < I_IMAGENONE ? I_IMAGENONE : imageIndex; - lvi->mask |= LVIF_IMAGE; } + else + { + lvi->iImage = I_IMAGENONE; + } if ( argumentExists(4) ) { setLviUserData(context, lvi, itemData); } - if ( argumentExists(5) ) - { - uint32_t flags = keyword2lvif(mask); - if ( flags == (uint32_t)-1 ) - { - return NULLOBJECT; - } - lvi->mask = flags; - } - if ( argumentExists(6) ) { lvi->state = keyword2lvis(itemState, false); @@ -3935,12 +4183,41 @@ { setLviGroupID(context, lvi, groupID); } + else + { + if ( ComCtl32Version >= COMCTL32_6_0 ) + { + lvi->iGroupId = I_GROUPIDNONE; + lvi->mask |= LVIF_GROUPID; + } + } if ( argumentExists(10) ) { setLviColumns(context, lvi, columns, 10); } + else + { + // Check if the user has set the LVIF_COLUMNS flag. + if ( lvi->mask & LVIF_COLUMNS ) + { + if ( ! allocLviColumns(context, lvi) ) + { + return NULLOBJECT; + } + } + } + // We want the user to be able to create the LvItem object to recieve data. + // So we check if the user has set the LVIF_COLFMT flag. + if ( lvi->mask & LVIF_COLFMT ) + { + if ( ! allocLviColFmt(context, lvi) ) + { + return NULLOBJECT; + } + } + return NULLOBJECT; } @@ -3994,7 +4271,6 @@ return 0; } ((LPLVITEM)pLVI)->iGroup = id; - ((LPLVITEM)pLVI)->mask |= LVIF_GROUPID; return NULLOBJECT; } @@ -4088,7 +4364,7 @@ */ RexxMethod1(int32_t, lvi_overlayImageIndex, CSELF, pLVI) { - return LVIS_OVERLAYMASK & ((LPLVITEM)pLVI)->state; + return (LVIS_OVERLAYMASK & ((LPLVITEM)pLVI)->state) >> 8; } RexxMethod2(RexxObjectPtr, lvi_setOverlayImageIndex, int32_t, index, CSELF, pLVI) { @@ -4101,7 +4377,7 @@ */ RexxMethod1(int32_t, lvi_stateImageIndex, CSELF, pLVI) { - return LVIS_STATEIMAGEMASK & ((LPLVITEM)pLVI)->state; + return (LVIS_STATEIMAGEMASK & ((LPLVITEM)pLVI)->state) >> 12; } RexxMethod2(RexxObjectPtr, lvi_setStateImageIndex, int32_t, index, CSELF, pLVI) { @@ -4112,7 +4388,7 @@ /** LvItem::text [attribute] */ -RexxMethod1(RexxStringObject, lvi_text, CSELF, pLVI) +RexxMethod1(RexxObjectPtr, lvi_text, CSELF, pLVI) { return getLviText(context, (LPLVITEM)pLVI); } @@ -4257,7 +4533,7 @@ /** LvSubItem::text [attribute] */ -RexxMethod1(RexxStringObject, lvsi_text, CSELF, pLVI) +RexxMethod1(RexxObjectPtr, lvsi_text, CSELF, pLVI) { return getLviText(context, (LPLVITEM)pLVI); } Modified: ooDialog/trunk/ooDialog/oodPackageEntry.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-12-01 05:51:19 UTC (rev 8649) +++ ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-12-01 20:19:24 UTC (rev 8650) @@ -1008,6 +1008,7 @@ REXX_METHOD_PROTOTYPE(lv_checkUncheck); REXX_METHOD_PROTOTYPE(lv_delete); REXX_METHOD_PROTOTYPE(lv_deleteAll); +REXX_METHOD_PROTOTYPE(lv_deleteColumn); REXX_METHOD_PROTOTYPE(lv_deselectAll); REXX_METHOD_PROTOTYPE(lv_find); REXX_METHOD_PROTOTYPE(lv_findNearestXY); @@ -2016,6 +2017,7 @@ REXX_METHOD(lv_checkUncheck, lv_checkUncheck), REXX_METHOD(lv_delete, lv_delete), REXX_METHOD(lv_deleteAll, lv_deleteAll), + REXX_METHOD(lv_deleteColumn, lv_deleteColumn), REXX_METHOD(lv_deselectAll, lv_deselectAll), REXX_METHOD(lv_find, lv_find), REXX_METHOD(lv_findNearestXY, lv_findNearestXY), |
From: <mie...@us...> - 2012-12-02 21:27:49
|
Revision: 8653 http://sourceforge.net/p/oorexx/code-0/8653 Author: miesfeld Date: 2012-12-02 21:27:47 +0000 (Sun, 02 Dec 2012) Log Message: ----------- Implement: #501 The ListView class should have an easy way to switch views See ticket [Feature-Requests:#501] Work on RFE: #478 ooDialog - List-view could use a way to work with a complete row See ticket [Feature-Requests:#478] Modified Paths: -------------- ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex ooDialog/trunk/ooDialog/ListView.cls ooDialog/trunk/ooDialog/oodListView.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp Modified: ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex =================================================================== --- ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex 2012-12-02 21:23:59 UTC (rev 8652) +++ ooDialog/trunk/examples/propertySheet.tabs/oodListViews.rex 2012-12-02 21:27:47 UTC (rev 8653) @@ -559,31 +559,14 @@ use strict arg index select - when index == 1 then do - oldStyle = "REPORT ICON SMALLICON" - newStyle = "LIST" - end - - when index == 2 then do - oldStyle = "LIST ICON SMALLICON" - newStyle = "REPORT" - end - - when index == 3 then do - oldStyle = "LIST REPORT SMALLICON" - newStyle = "ICON" - end - - when index == 4 then do - oldStyle = "LIST REPORT ICON" - newStyle = "SMALLICON" - end - + when index == 1 then lv~setView("LIST") + when index == 2 then lv~setView("REPORT") + when index == 3 then lv~setView("ICON") + when index == 4 then lv~setView("SMALLICON") otherwise return .false end -- End select - lv~replaceStyle(oldStyle, newStyle) return .true Modified: ooDialog/trunk/ooDialog/ListView.cls =================================================================== --- ooDialog/trunk/ooDialog/ListView.cls 2012-12-02 21:23:59 UTC (rev 8652) +++ ooDialog/trunk/ooDialog/ListView.cls 2012-12-02 21:27:47 UTC (rev 8653) @@ -155,6 +155,7 @@ ::method getItemPos unguarded external "LIBRARY oodialog lv_getItemPos" ::method getSubitem unguarded external "LIBRARY oodialog lv_getSubitem" ::method getToolTips unguarded external "LIBRARY oodialog generic_getToolTips" +::method getView unguarded external "LIBRARY oodialog lv_getView" ::method hasCheckBoxes unguarded external "LIBRARY oodialog lv_hasCheckBoxes" ::method hitTestInfo unguarded external "LIBRARY oodialog lv_hitTestInfo" ::method insert unguarded external "LIBRARY oodialog lv_insert" @@ -253,6 +254,7 @@ ::method setItemState unguarded external "LIBRARY oodialog lv_setItemState" ::method setItemText unguarded external "LIBRARY oodialog lv_setItemText" ::method setToolTips unguarded external "LIBRARY oodialog generic_setToolTips" +::method setView unguarded external "LIBRARY oodialog lv_setView" ::method smallSpacing unguarded return self~sendWinIntMsg(self~LVM_GETITEMSPACING, 1, 0) @@ -276,31 +278,29 @@ ::method updateItem unguarded use strict arg index - return self~sendWinIntMsg(self~LVM_UPDATE, index, 0) <> 0 + return self~sendWinIntMsg(self~LVM_UPDATE, index, 0) == 0 --- DEPRECATED -::method removeImages unguarded -- DEPRECATED +::method zTest unguarded external "LIBRARY oodialog lv_zTest" + +-- DEPRECATED to end of Class +::method removeImages unguarded -- DEPRECATED return self~removeImageList(.nil, 0) --- DEPRECATED -::method removeSmallImages unguarded + +::method removeSmallImages unguarded -- DEPRECATED return self~removeImageList(.nil, 1) --- DEPRECATED -::method restoreEditClass +::method restoreEditClass -- DEPRECATED --- DEPRECATED -::method setImages unguarded external "LIBRARY oodialog lv_setImageList" +::method setImages unguarded external "LIBRARY oodialog lv_setImageList" -- DEPRECATED --- DEPRECATED -::method setSmallImages unguarded +::method setSmallImages unguarded -- DEPRECATED newArgs = arg(1, 'A') newArgs[4] = 1 forward message 'setImageList' arguments (newArgs) --- DEPRECATED -::method subclassEdit +::method subclassEdit -- DEPRECATED ::class 'LvCustomDrawSimple' public @@ -357,7 +357,7 @@ ::attribute text set external "LIBRARY oodialog lvi_setText" -::class 'LvFullRow' public -- Do not document for 4.2.0 +::class 'LvFullRow' public ::method init external "LIBRARY oodialog lvfr_init" ::method unInit external "LIBRARY oodialog lvfr_unInit" @@ -368,7 +368,7 @@ ::method subItems external "LIBRARY oodialog lvfr_subitems" -::class 'LvSubItem' public -- Do not document for 4.2.0 +::class 'LvSubItem' public ::method init external "LIBRARY oodialog lvsi_init" ::method unInit external "LIBRARY oodialog lvsi_unInit" Modified: ooDialog/trunk/ooDialog/oodListView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-02 21:23:59 UTC (rev 8652) +++ ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-02 21:27:47 UTC (rev 8653) @@ -247,6 +247,17 @@ } +static RexxStringObject view2keyword(RexxMethodContext *c, uint32_t view) +{ + if ( view == LV_VIEW_ICON ) return c->String("ICON"); + else if ( view == LV_VIEW_SMALLICON ) return c->String("SMALLICON"); + else if ( view == LV_VIEW_LIST ) return c->String("LIST"); + else if ( view == LV_VIEW_DETAILS ) return c->String("REPORT"); + + return c->NullString(); +} + + /** * Produce a string representation of a List-View's extended styles. */ @@ -518,44 +529,21 @@ * @param pclvfr * * @assumes updateFullRowIndexes() has already been invoked. - * - * @remarks Originally, this function just updated the state member of the - * struct. But now it does a fresh ListView_Item() with all flags for - * the mask being set. This should make sure the Rexx LvItem object - * accurately reflects the current state of underlying list-view item. - * - * But, it is changing what the mask value is from what the Rexx user - * may have set. I think this is okay, but it sort of depends on how - * well the list-view implementation follows what the MSDN docs say - * ... - * - * There is one problem with the groupId field of the LVITEM struct. - * If the LVIF_GROUPID flag is set and there is no group ID in the - * item, the OS does not seem to update the groupId field to - * I_GROUPIDNONE (-2). If the LVITEM struct is then used to insert the - * item with LVIF_GROUPID still set and the groupId field set to 0, - * the insert field fails. If the field is already set to -2, things - * are okay. Have not had a chance to test when the field is say 2. - * For now, if the field comes back 0, we change it to I_GROUPID_NONE. */ -static void updateFullRowItemState(RexxMethodContext *c, pCLvFullRow pclvfr) +static void updateFullRowItemState(pCLvFullRow pclvfr) { if ( pclvfr->hList != NULL ) { LPLVITEM pLvi = pclvfr->subItems[0]; + LVITEM lvi = {0}; - if ( ! ensureLvItemBuffers(c, pLvi) ) - { - return; - } + lvi.iItem = pLvi->iItem; + lvi.mask = LVIF_STATE; + lvi.stateMask = (uint32_t)-1; - pLvi->mask = LVITEM_ALL_MASK; - pLvi->stateMask = (uint32_t)-1; - - ListView_GetItem(pclvfr->hList, pLvi); - if ( pLvi->iGroupId == 0 ) + if ( ListView_GetItem(pclvfr->hList, &lvi) ) { - pLvi->iGroupId = I_GROUPIDNONE; + pLvi->state = lvi.state; } } } @@ -580,7 +568,7 @@ * * If subitem is out of bounds then we just do nothing. */ -static void resetFullRowText(RexxMethodContext *c, pCLvFullRow pclvfr, uint32_t subitem, CSTRING text) +static void updateFullRowText(RexxMethodContext *c, pCLvFullRow pclvfr, uint32_t subitem, CSTRING text) { if ( subitem <= pclvfr->subItemCount ) { @@ -714,7 +702,7 @@ } if ( LVIF_TEXT & lvi->mask ) { - resetFullRowText(c, pclvfr, 0, lvi->pszText); + updateFullRowText(c, pclvfr, 0, lvi->pszText); } if ( LVIF_STATE & lvi->mask ) { @@ -1538,10 +1526,10 @@ return changeStyle(context, (pCDialogControl)pCSelf, style, NULL, (*method == 'R')); } -/** ListView::arrange() +/** ListView::alignLeft() + * ListView::arrange() + * Listview::alignTop() * ListView::snaptoGrid() - * ListView::alignLeft() - * Listview::alignTop() * * @remarks MSDN says of ListView_Arrange(): * @@ -1612,6 +1600,36 @@ return -1; } +/** ListView::BkColor= + * ListView::TextColor= + * ListView::TextBkColor= + * + * + * @remarks. This method is hopelessly outdated. It should take a COLORREF so + * that the user has access to all available colors rather than be + * limited to 18 colors out of a 256 color display. + */ +RexxMethod3(RexxObjectPtr, lv_setColor, uint32_t, color, NAME, method, CSELF, pCSelf) +{ + HWND hList = getDChCtrl(pCSelf); + + COLORREF ref = PALETTEINDEX(color); + + if ( *method == 'B' ) + { + ListView_SetBkColor(hList, ref); + } + else if ( method[4] == 'C' ) + { + ListView_SetTextColor(hList, ref); + } + else + { + ListView_SetTextBkColor(hList, ref); + } + return NULLOBJECT; +} + /** ListView::check() ** ListView::uncheck() * @@ -1985,23 +2003,52 @@ * internal sorting, this must be set to true. * * @remarks We first check to see if a LvFullRow object is the stored user - * data for the list-view item. If it is, we just return that. When - * we have a LvFullRow object as the item user data, we have code - * that keeps the LvFullRow object updated when changes are made to - * the item. We need to be sure and maintain that. + * data for the list-view item. If it is, we just return that. * - * maybeGetFullRow() updates the item index in the Rexx objects to - * the correct index. But we also need to do - * updateFullRowItemState() to be sure and get the current state. - * TODO !!! we also need a updateFullRowSubItemStates(). Maybe ?? + * ------------------------------------------------------------ * + * IMPORTANT: The current approach we take for LvFullRow objects set + * as the item's lParam (user data) is this: For each ListView + * method that alters (modifies) a list-view item's data, we check if + * we have a LvFullRow object as the item user data. If so, we update + * the LvFullRow object with the modified data. We need to be sure + * and maintain that. + * + * Item indexes. Inserting and deleting items will change the item + * index in the LvFullRow objects. Rather than trying to fix up the + * indexes for all LvFullRow objects during an insert of delete, we + * just fix up the index at the time the user requests a full row, or + * a full row object. The maybeGetFullRow() method updates the item + * index in the Rexx objects to the correct index, if needed. (We + * are using ListView_MapIDToIndex() and ListView_MapIndexToID() to + * keep indexes correct.) + * + * Transitory state. State such as selected, focused, etc., can be + * changed and can not be managed by monitoring ListView methods. For + * this we the use the updateFullRowItemState() method to get the + * current transitory item state before we return a full row object + * to the user. + * + * This same basic principle is used for the objects a full row + * contains, LvItem and LvSubItem objects. + * + * The one remaining problem is if the user deletes or inserts new + * columns. If this happens, the LvFullRow objects all need to be + * fixed up. We could either monitor the deleteColumn() and + * insertColumn() methods and fix all LvFullRow objects during those + * methods, or add some method that allows the user to trigger a fix + * up. ? Undecided. Fix ups during deleteColumn() / insertColumn() + * may be time consuming and for insertColumn() will involve creating + * a bunch of LvSubItem objects with no state ... + * + * ----------------------------------------------------------- + * * If there is no LvFullRow object as the user data, the most likely * case, we create the object here. We do that by creating Rexx - * objects for the item and for any subitems we can detect. - * Detecting the subitems is dependent on the coulumn count. Testing - * has shown that once the column is inserted, getColumnCount() - * returns the correct number, even if the list-view is not in report - * view. + * objects for the item and for any subitems we can detect. Detecting + * the subitems is dependent on the coulumn count. Testing has shown + * that once the column is inserted, getColumnCount() returns the + * correct number, even if the list-view is not in report view. */ RexxMethod3(RexxObjectPtr, lv_getFullRow, uint32_t, itemIndex, OPTIONAL_logical_t, useForSorting, CSELF, pCSelf) { @@ -2011,11 +2058,12 @@ pCLvFullRow pclvfr = maybeGetFullRow(hList, itemIndex); if ( pclvfr != NULL ) { - updateFullRowItemState(context, pclvfr); + updateFullRowItemState(pclvfr); return pclvfr->rexxSelf; } - // Okay, create a LvFullRow object from the current state of the item: + // Okay, no LvFullRow object as the user data (lParam), so create a + // LvFullRow object from the current state of the item: // Create a LvItem RexxObjectPtr rxItem = newLvItem(context, hList, itemIndex); @@ -2136,12 +2184,19 @@ * * Returns, or fills in, a LvItem object for the item specified. * - * @param _item [required] Can be a LvItem object or the item index. If it is - * a LvItem, we just fill it in. If it is an index and we have - * no LvFullRow, we return a new, filled in, LvItem object. If - * we do have a LvFullRow, we update the LVITEM struct for the - * item and then return the Rexx LvItem. + * @param _item [required] Can be a LvItem object or the item index. * + * If it is a LvItem, we just fill it in. + * + * If it is an index and we have no LvFullRow, we return a new, + * instantiated, LvItem object that reflects the item and the + * item's current state. + * + * If we do have a LvFullRow, we ensure the LvFullRow objects + * have the item indexes in sync and update the LvItem with the + * current transitory state, and then return the Rexx LvItem from + * the full row. + * * @remarks If we have a LvFullRow object assigned to the user data, we use * the Rexx item in the full row. maybeGetFullRow() will update the item * index, and then updateFullRowItemState will sync the LVITEM struct by doing @@ -2158,7 +2213,7 @@ LPLVITEM plvi = (LPLVITEM)context->ObjectToCSelf(_item); BOOL success = ListView_GetItem(hList, plvi); - if ( success && (plvi->mask & LVIF_GROUPID) && plvi->iGroupId ) + if ( success && (plvi->mask & LVIF_GROUPID) && plvi->iGroupId == 0 ) { plvi->iGroupId = I_GROUPIDNONE; } @@ -2176,7 +2231,7 @@ pCLvFullRow pclvfr = maybeGetFullRow(hList, itemIndex); if ( pclvfr != NULL ) { - updateFullRowItemState(context, pclvfr); + updateFullRowItemState(pclvfr); result = pclvfr->rxSubItems[0]; } else @@ -2315,94 +2370,12 @@ return rxNewPoint(context, p.x, p.y); } -/** ListView::next() - * ListView::nextSelected() - * ListView::nextLeft() - * ListView::nextRight() - * ListView::previous() - * ListView::previousSelected() - * - * - * @remarks For the next(), nextLeft(), nextRight(), and previous() methods, - * we had this comment: - * - * The Windows API appears to have a bug when the list contains a - * single item, insisting on returning 0. This, rather - * unfortunately, can cause some infinite loops because iterating - * code is looking for a -1 value to mark the iteration end. - * - * And in the method did: if self~Items < 2 then return -1 - * - * In this code, that check is not added yet, and the whole premise - * needs to be tested. I find no mention of this bug in any Google - * searches I have done, and it seems odd that we are the only people - * that know about the bug? - */ -RexxMethod3(int32_t, lv_getNextItem, OPTIONAL_int32_t, startItem, NAME, method, CSELF, pCSelf) -{ - uint32_t flag; - - if ( *method == 'N' ) - { - switch ( method[4] ) - { - case '\0' : - flag = LVNI_BELOW | LVNI_TORIGHT; - break; - case 'S' : - flag = LVNI_BELOW | LVNI_TORIGHT | LVNI_SELECTED; - break; - case 'L' : - flag = LVNI_TOLEFT; - break; - default : - flag = LVNI_TORIGHT; - break; - } - } - else - { - flag = (method[8] == 'S' ? LVNI_ABOVE | LVNI_TOLEFT | LVNI_SELECTED : LVNI_ABOVE | LVNI_TOLEFT); - } - - if ( argumentOmitted(1) ) - { - startItem = -1; - } - return ListView_GetNextItem(getDChCtrl(pCSelf), startItem, flag); -} - -/** ListView::selected() - * ListView::focused() - * ListView::dropHighlighted() - * - * - */ -RexxMethod2(int32_t, lv_getNextItemWithState, NAME, method, CSELF, pCSelf) -{ - uint32_t flag; - - if ( *method == 'S' ) - { - flag = LVNI_SELECTED; - } - else if ( *method == 'F' ) - { - flag = LVNI_FOCUSED; - } - else - { - flag = LVNI_DROPHILITED; - } - return ListView_GetNextItem(getDChCtrl(pCSelf), -1, flag); -} - /** ListView::getSubitem() * * Returns a LvSubItem object for the item and subitem indexes specified. * * @remarks The ListView_GetItem macro will not fail, even if the subitem - * index is greater than any existing subitem. Text is the empty + * index is greater than any existing subitem. * string. Plus, there is no reason that the user could not have * added subitems, but the list-view is not in report view. So, we * don't check subitemIndex with getColumnCount() @@ -2437,6 +2410,25 @@ return result; } +/** ListView::getView() + * + * + */ +RexxMethod1(RexxObjectPtr, lv_getView, CSELF, pCSelf) +{ + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) + { + return context->NullString(); + } + if ( ! requiredComCtl32Version(context, "ListView::setView", COMCTL32_6_0) ) + { + return context->NullString(); + } + + return view2keyword(context, ListView_GetView(pcdc->hCtrl)); +} + /** ListView::hasCheckBoxes() */ RexxMethod1(RexxObjectPtr, lv_hasCheckBoxes, CSELF, pCSelf) @@ -2799,37 +2791,27 @@ return context->String(buf); } -/** ListView::setColumnWidthPX() +/** ListView::modify() * + * Modifies the text and or image index for an item. Or the text only for a + * subitem. * - */ -RexxMethod3(RexxObjectPtr, lv_setColumnWidthPx, uint32_t, index, OPTIONAL_RexxObjectPtr, _width, CSELF, pCSelf) -{ - HWND hList = getDChCtrl(pCSelf); - - int width = getColumnWidthArg(context, _width, 2); - if ( width == OOD_BAD_WIDTH_EXCEPTION ) - { - return TheOneObj; - } - - if ( width == LVSCW_AUTOSIZE || width == LVSCW_AUTOSIZE_USEHEADER ) - { - if ( !isInReportView(hList) ) - { - userDefinedMsgException(context->threadContext, 2, "can not be AUTO or AUTOHEADER if not in report view"); - return TheOneObj; - } - } - - return (ListView_SetColumnWidth(hList, index, width) ? TheZeroObj : TheOneObj); -} - -/** ListView::modify() + * @remarks The docs for the imageIndex argument have read: Use -1 or simply + * omit this argument to leave the icon index unchanged. If subitem + * is greater than 0, this argument is ignored. So, we want to + * preserve that, which means this method can not be used to update + * the image index for subitems. * + * @remarks If the user has a LvFullRox object as the user data, we update the + * values in that object after a successful modify(). The user can + * only change text and image index in the item here. And only text + * in a subitem. * - * @remarks If the user has a LvFullRox object as the user data, we update the - * values in that object after a successful modify(). + * Testing has shown that if subItemIndex is greater than the column + * count, then ListView_SetItem() will fail. MSDN says that all + * items in a list-view have the same number of subitems. So, we do + * not test that the subitemIndex is within the number of columns. + * If it is not, the ListView_SetItem() call will fail. */ RexxMethod5(RexxObjectPtr, lv_modify, OPTIONAL_uint32_t, itemIndex, OPTIONAL_uint32_t, subitemIndex, CSTRING, text, OPTIONAL_int32_t, imageIndex, CSELF, pCSelf) @@ -2847,7 +2829,7 @@ } } itemIndex = (argumentOmitted(1) ? getSelected(hList) : itemIndex); - imageIndex = (argumentOmitted(4) ? -1 : imageIndex); + imageIndex = (argumentExists(4) && subitemIndex == 0 ? imageIndex : -1); if ( itemIndex < 0 ) { @@ -2873,7 +2855,7 @@ pCLvFullRow pclvfr = maybeGetFullRow(hList, itemIndex); if ( pclvfr != NULL ) { - resetFullRowText(context, pclvfr, subitemIndex, text); + updateFullRowText(context, pclvfr, subitemIndex, text); if ( imageIndex > -1 && subitemIndex <= pclvfr->subItemCount ) { @@ -3006,6 +2988,74 @@ return FALSE; } +/** ListView::next() + * ListView::nextSelected() + * ListView::nextLeft() + * ListView::nextRight() + * ListView::previous() + * ListView::previousSelected() + * + * + * @remarks For the next(), nextLeft(), nextRight(), and previous() methods, + * we had this comment: + * + * The Windows API appears to have a bug when the list contains a + * single item, insisting on returning 0. This, rather + * unfortunately, can cause some infinite loops because iterating + * code is looking for a -1 value to mark the iteration end. + * + * And in the method did: if self~Items < 2 then return -1 + * + * In this code, that check is not added yet, and the whole premise + * needs to be tested. I find no mention of this bug in any Google + * searches I have done, and it seems odd that we are the only people + * that know about the bug? + */ +RexxMethod3(int32_t, lv_getNextItem, OPTIONAL_int32_t, startItem, NAME, method, CSELF, pCSelf) +{ + uint32_t flag; + + if ( *method == 'N' ) + { + switch ( method[4] ) + { + case '\0' : + flag = LVNI_BELOW | LVNI_TORIGHT; + break; + case 'S' : + flag = LVNI_BELOW | LVNI_TORIGHT | LVNI_SELECTED; + break; + case 'L' : + flag = LVNI_TOLEFT; + break; + default : + flag = LVNI_TORIGHT; + break; + } + } + else + { + flag = (method[8] == 'S' ? LVNI_ABOVE | LVNI_TOLEFT | LVNI_SELECTED : LVNI_ABOVE | LVNI_TOLEFT); + } + + if ( argumentOmitted(1) ) + { + startItem = -1; + } + return ListView_GetNextItem(getDChCtrl(pCSelf), startItem, flag); +} + +/** ListView::prependFullRow() + * + * Adds an item to the list view at the beginning of the list using a LvFullRow + * object. + * + */ +RexxMethod2(int32_t, lv_prependFullRow, RexxObjectPtr, row, CSELF, pCSelf) +{ + return fullRowOperation(context, row, lvfrInsert, pCSelf); +} + /** ListView::removeItemData() * * @remarks Note that if the lParam user data is a LvFullRow object, there is @@ -3081,61 +3131,45 @@ if ( *method == 'S' ) { - mask |= LVIS_SELECTED; - state |= LVIS_SELECTED; + mask = LVIS_SELECTED; + state = LVIS_SELECTED; } else if ( *method == 'D' ) { - mask |= LVIS_SELECTED; + mask = LVIS_SELECTED; } else { - mask |= LVIS_FOCUSED; - state |= LVIS_FOCUSED; + mask = LVIS_FOCUSED; + state = LVIS_FOCUSED; } ListView_SetItemState(getDChCtrl(pCSelf), index, state, mask); return TheZeroObj; } -/** ListView::prependFullRow() +/** ListView::selected() + * ListView::focused() + * ListView::dropHighlighted() * - * Adds an item to the list view at the beginning of the list using a LvFullRow - * object. * */ -RexxMethod2(int32_t, lv_prependFullRow, RexxObjectPtr, row, CSELF, pCSelf) +RexxMethod2(int32_t, lv_getNextItemWithState, NAME, method, CSELF, pCSelf) { - return fullRowOperation(context, row, lvfrInsert, pCSelf); -} + uint32_t flag; -/** ListView::BkColor= - * ListView::TextColor= - * ListView::TextBkColor= - * - * - * @remarks. This method is hopelessly outdated. It should take a COLORREF so - * that the user has access to all available colors rather than be - * limited to 18 colors out of a 256 color display. - */ -RexxMethod3(RexxObjectPtr, lv_setColor, uint32_t, color, NAME, method, CSELF, pCSelf) -{ - HWND hList = getDChCtrl(pCSelf); - - COLORREF ref = PALETTEINDEX(color); - - if ( *method == 'B' ) + if ( *method == 'S' ) { - ListView_SetBkColor(hList, ref); + flag = LVNI_SELECTED; } - else if ( method[4] == 'C' ) + else if ( *method == 'F' ) { - ListView_SetTextColor(hList, ref); + flag = LVNI_FOCUSED; } else { - ListView_SetTextBkColor(hList, ref); + flag = LVNI_DROPHILITED; } - return NULLOBJECT; + return ListView_GetNextItem(getDChCtrl(pCSelf), -1, flag); } /** ListView::setColumnOrder() @@ -3195,6 +3229,32 @@ return success; } +/** ListView::setColumnWidthPX() + * + * + */ +RexxMethod3(RexxObjectPtr, lv_setColumnWidthPx, uint32_t, index, OPTIONAL_RexxObjectPtr, _width, CSELF, pCSelf) +{ + HWND hList = getDChCtrl(pCSelf); + + int width = getColumnWidthArg(context, _width, 2); + if ( width == OOD_BAD_WIDTH_EXCEPTION ) + { + return TheOneObj; + } + + if ( width == LVSCW_AUTOSIZE || width == LVSCW_AUTOSIZE_USEHEADER ) + { + if ( !isInReportView(hList) ) + { + userDefinedMsgException(context->threadContext, 2, "can not be AUTO or AUTOHEADER if not in report view"); + return TheOneObj; + } + } + + return (ListView_SetColumnWidth(hList, index, width) ? TheZeroObj : TheOneObj); +} + /** ListView::setImageList() * * Sets or removes one of a list-view's image lists. @@ -3458,13 +3518,47 @@ pCLvFullRow pclvfr = maybeGetFullRow(hList, index); if ( pclvfr != NULL ) { - resetFullRowText(context, pclvfr, subitem, text); + updateFullRowText(context, pclvfr, subitem, text); } ListView_SetItemText(hList, index, subitem, (LPSTR)text); return TheZeroObj; } +/** ListView::setView() + * + * + */ +RexxMethod2(RexxObjectPtr, lv_setView, CSTRING, view, CSELF, pCSelf) +{ + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) + { + return context->NullString(); + } + if ( ! requiredComCtl32Version(context, "ListView::setView", COMCTL32_6_0) ) + { + return context->NullString(); + } + + uint32_t style = 0; + uint32_t old = ListView_GetView(pcdc->hCtrl); + + if ( StrCmpI(view, "ICON" ) == 0 ) style = LV_VIEW_ICON; + else if ( StrCmpI(view, "SMALLICON") == 0 ) style = LV_VIEW_SMALLICON; + else if ( StrCmpI(view, "LIST" ) == 0 ) style = LV_VIEW_LIST; + else if ( StrCmpI(view, "REPORT" ) == 0 ) style = LV_VIEW_DETAILS; + else + { + wrongArgValueException(context->threadContext, 1, "Icon, SmallIcon, List, or Report", view); + return context->NullString(); + } + + ListView_SetView(pcdc->hCtrl, style); + + return view2keyword(context, old); +} + /** ListView::sortItems() * * @@ -3496,7 +3590,75 @@ return ListView_GetStringWidth(getDChCtrl(pCSelf), text); } +/** ListView::zTest() + * + * An undocumented method to make it easier to do development testing + * + */ +RexxMethod3(RexxObjectPtr, lv_zTest, uint32_t, itemIndex, uint32_t, subItemIndex, CSELF, pCSelf) +{ + printf("zTest() itemIndex=%d subItemIndex=%d\n", itemIndex, subItemIndex); + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) + { + return TheFalseObj; + } + + /* + LVCOLUMN lvc = { 0 }; + lvc.mask = LVCF_WIDTH | LVCF_SUBITEM; + if ( ListView_GetColumn(pcdc->hCtrl, subItemIndex, &lvc) ) + { + printf("ListView_GetColumn() returns TRUE lvc.iSubItem=%d\n", lvc.iSubItem); + } + else + { + printf("ListView_GetColumn() returns FALSE lvc.iSubItem=%d\n", lvc.iSubItem); + } + */ + + + LVITEM lvi = { 0 }; + lvi.iItem = itemIndex; + lvi.iSubItem = subItemIndex; + lvi.mask = LVIF_TEXT | LVIF_IMAGE; + + //char buf[1024] = { '\0' }; + char buf[1024] = "My subitem text"; + lvi.pszText = buf; + lvi.cchTextMax = 1024; + + printf("pszText=%p\n", lvi.pszText); + /* + if ( ListView_GetItem(pcdc->hCtrl, &lvi) ) + { + printf("ListView_GetItem() returns TRUE imageIndex=%d pszText=%p pszText == LPSTR_TEXTCALLBACK=%d\n", + lvi.iImage, lvi.pszText, lvi.pszText == LPSTR_TEXTCALLBACK); + if ( lvi.pszText != NULL && lvi.pszText != LPSTR_TEXTCALLBACK ) + { + printf("Got text=%s\n", lvi.pszText); + } + } + else + { + printf("ListView_GetItem() returns FALSE\n"); + } + */ + + if ( ListView_SetItem(pcdc->hCtrl, &lvi) ) + { + printf("ListView_SetItem() returns TRUE\n"); + } + else + { + printf("ListView_SetItem() returns FALSE\n"); + } + + return TheTrueObj; +} + + /** * Methods for the .LvItem class. */ @@ -3702,6 +3864,11 @@ { return TheNilObj; } + else if ( pLVI->pszText == LPSTR_TEXTCALLBACK ) + { + return c->String("lpStrTextCallBack"); + } + return c->String(pLVI->pszText); } @@ -3717,6 +3884,8 @@ * simplier, we only allow the Rexx programmer to use a string up to 260 TCHARS. * This is only enforced here, not currently enforced in the ListView class. * + * We use lpStrTextCallBack as the string to indicate the call back value. + * * @param c * @param pLVI * @param text @@ -3725,6 +3894,13 @@ */ bool setLviText(RexxMethodContext *c, LPLVITEM pLVI, CSTRING text, size_t argPos) { + if ( StrCmpI(text, "lpStrTextCallBack") == 0 ) + { + pLVI->pszText = LPSTR_TEXTCALLBACK; + pLVI->cchTextMax = 0; + return true; + } + size_t len = strlen(text); bool receiving = (len == 0 ? true : false); Modified: ooDialog/trunk/ooDialog/oodPackageEntry.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-12-02 21:23:59 UTC (rev 8652) +++ ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-12-02 21:27:47 UTC (rev 8653) @@ -1028,6 +1028,7 @@ REXX_METHOD_PROTOTYPE(lv_getNextItem); REXX_METHOD_PROTOTYPE(lv_getNextItemWithState); REXX_METHOD_PROTOTYPE(lv_getSubitem); +REXX_METHOD_PROTOTYPE(lv_getView); REXX_METHOD_PROTOTYPE(lv_hasCheckBoxes); REXX_METHOD_PROTOTYPE(lv_hitTestInfo); REXX_METHOD_PROTOTYPE(lv_insert); @@ -1052,8 +1053,10 @@ REXX_METHOD_PROTOTYPE(lv_setItemState); REXX_METHOD_PROTOTYPE(lv_setItemText); REXX_METHOD_PROTOTYPE(lv_setSpecificState); +REXX_METHOD_PROTOTYPE(lv_setView); REXX_METHOD_PROTOTYPE(lv_sortItems); REXX_METHOD_PROTOTYPE(lv_stringWidthPx); +REXX_METHOD_PROTOTYPE(lv_zTest); // LvItem REXX_METHOD_PROTOTYPE(lvi_init ); @@ -2037,6 +2040,7 @@ REXX_METHOD(lv_getNextItem, lv_getNextItem), REXX_METHOD(lv_getNextItemWithState, lv_getNextItemWithState), REXX_METHOD(lv_getSubitem, lv_getSubitem), + REXX_METHOD(lv_getView, lv_getView), REXX_METHOD(lv_hasCheckBoxes, lv_hasCheckBoxes), REXX_METHOD(lv_hitTestInfo, lv_hitTestInfo), REXX_METHOD(lv_insert, lv_insert), @@ -2063,6 +2067,8 @@ REXX_METHOD(lv_setSpecificState, lv_setSpecificState), REXX_METHOD(lv_sortItems, lv_sortItems), REXX_METHOD(lv_stringWidthPx, lv_stringWidthPx), + REXX_METHOD(lv_setView, lv_setView), + REXX_METHOD(lv_zTest, lv_zTest), // LvItem REXX_METHOD(lvi_init, lvi_init), |
From: <mie...@us...> - 2012-12-04 03:49:01
|
Revision: 8656 http://sourceforge.net/p/oorexx/code-0/8656 Author: miesfeld Date: 2012-12-04 03:48:57 +0000 (Tue, 04 Dec 2012) Log Message: ----------- Work on RFE: #478 ooDialog - List-view could use a way to work with a complete row See ticket [Feature-Requests:#478] Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/ooDialog/ListView.cls ooDialog/trunk/ooDialog/oodCommon.hpp ooDialog/trunk/ooDialog/oodListView.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-03 04:10:04 UTC (rev 8655) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-04 03:48:57 UTC (rev 8656) @@ -129,7 +129,9 @@ * #499 ooDialog connectTreeViewEvent CHANGING veto +* #501 The ListView class should have an easy way to switch views + New Functionality in ooDialog: ------------------------------ Modified: ooDialog/trunk/ooDialog/ListView.cls =================================================================== --- ooDialog/trunk/ooDialog/ListView.cls 2012-12-03 04:10:04 UTC (rev 8655) +++ ooDialog/trunk/ooDialog/ListView.cls 2012-12-04 03:48:57 UTC (rev 8656) @@ -135,6 +135,7 @@ ::method firstVisible unguarded return self~sendWinIntMsg(self~LVM_GETTOPINDEX , 0, 0) +::method fixFullRowColumns unguarded external "LIBRARY oodialog lv_fixFullRowColumns" ::method focus unguarded external "LIBRARY oodialog lv_setSpecificState" ::method focused unguarded external "LIBRARY oodialog lv_getNextItemWithState" ::method getCheck unguarded external "LIBRARY oodialog lv_getCheck" @@ -160,9 +161,9 @@ ::method hitTestInfo unguarded external "LIBRARY oodialog lv_hitTestInfo" ::method insert unguarded external "LIBRARY oodialog lv_insert" ::method insertColumn unguarded -- Dialog units, not accurate. - use strict arg nr = 0, text, width, fmt = "L" + use strict arg nr = 0, text, width, fmt = "L", adjustFullRows = .false width = trunc(width * self~factorX) - return self~insertColumnPx(nr, text, width, fmt) + return self~insertColumnPx(nr, text, width, fmt, adjustFullRows) ::method insertColumnPx unguarded external "LIBRARY oodialog lv_insertColumnPx" ::method insertFullRow unguarded external "LIBRARY oodialog lv_insertFullRow" @@ -207,6 +208,7 @@ ::method modifyColumnPx unguarded external "LIBRARY oodialog lv_modifyColumnPx" ::method modifyItem unguarded external "LIBRARY oodialog lv_modifyItem" +::method modifySubitem unguarded external "LIBRARY oodialog lv_modifySubitem" ::method next unguarded external "LIBRARY oodialog lv_getNextItem" ::method nextLeft unguarded external "LIBRARY oodialog lv_getNextItem" ::method nextRight unguarded external "LIBRARY oodialog lv_getNextItem" @@ -362,6 +364,7 @@ ::method unInit external "LIBRARY oodialog lvfr_unInit" ::method addSubItem external "LIBRARY oodialog lvfr_addSubitem" +::method insertSubitem external "LIBRARY oodialog lvfr_insertSubitem" ::method item external "LIBRARY oodialog lvfr_item" ::method removeSubItem external "LIBRARY oodialog lvfr_removeSubitem" ::method subItem external "LIBRARY oodialog lvfr_subitem" Modified: ooDialog/trunk/ooDialog/oodCommon.hpp =================================================================== --- ooDialog/trunk/ooDialog/oodCommon.hpp 2012-12-03 04:10:04 UTC (rev 8655) +++ ooDialog/trunk/ooDialog/oodCommon.hpp 2012-12-04 03:48:57 UTC (rev 8656) @@ -243,7 +243,7 @@ inline void safeLocalFree(void *p) { - if (p != NULL) + if ( p != NULL && p != LPSTR_TEXTCALLBACK ) { LocalFree(p); } @@ -251,7 +251,7 @@ inline void safeFree(void *p) { - if (p != NULL) + if ( p != NULL ) { free(p); } @@ -259,7 +259,7 @@ inline void safeDeleteObject(HANDLE h) { - if (h != NULL) + if ( h != NULL ) { DeleteObject(h); } Modified: ooDialog/trunk/ooDialog/oodListView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-03 04:10:04 UTC (rev 8655) +++ ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-04 03:48:57 UTC (rev 8656) @@ -54,19 +54,32 @@ /** * Methods for the .ListView class. */ -#define LISTVIEW_CLASS "ListView" +#define LISTVIEW_CLASS "ListView" -#define LVSTATE_ATTRIBUTE "LV!STATEIMAGELIST" -#define LVSMALL_ATTRIBUTE "LV!SMALLIMAGELIST" -#define LVNORMAL_ATTRIBUTE "LV!NORMALIMAGELIST" +#define LVSTATE_ATTRIBUTE "LV!STATEIMAGELIST" +#define LVSMALL_ATTRIBUTE "LV!SMALLIMAGELIST" +#define LVNORMAL_ATTRIBUTE "LV!NORMALIMAGELIST" -#define LVITEM_ALL_MASK LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE | LVIF_INDENT | LVIF_COLUMNS | LVIF_COLFMT | LVIF_GROUPID | LVIF_NORECOMPUTE -#define LVITEM_TEXT_MAX 260 -#define LVITEM_TILECOLUMN_MAX 20 // According to MSDN +#define LVITEM_ALL_MASK LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE | LVIF_INDENT | LVIF_COLUMNS | LVIF_COLFMT | LVIF_GROUPID | LVIF_NORECOMPUTE +#define LVITEM_TEXT_MAX 260 +#define LVITEM_TILECOLUMN_MAX 20 // According to MSDN +#define LPSTR_TEXTCALLBACK_STRING "lpStrTextCallBack" -#define LVITEM_OBJ_MAGIC "mv12fa2t@" -#define LVSUBITEM_OBJ_MAGIC "L1sw2h2ww" +#define LVITEM_OBJ_MAGIC "mv12fa2t@" +#define LVSUBITEM_OBJ_MAGIC "L1sw2h2ww" +/** + * Prototypes for local functions that are too hard to move around to eliminate + * the need for the prototypes. + * + */ +static bool validColumnIndex(pCLvFullRow pclvfr, bool removed, uint32_t colIndex); +static RexxObjectPtr removeSubItemFromRow(RexxMethodContext *c, pCLvFullRow pclvfr, uint32_t index); +static RexxObjectPtr insertSubItemIntoRow(RexxMethodContext *c, RexxObjectPtr lvSubitem, pCLvFullRow pclvfr, uint32_t index); + + + + inline bool hasCheckBoxes(HWND hList) { return ((ListView_GetExtendedListViewStyle(hList) & LVS_EX_CHECKBOXES) != 0); @@ -320,6 +333,51 @@ } /** + * Checks for a LPSTR_TEXTCALLBACK in the pszText field of a LVITEM struct. + * + * @param lvi Pointer to struct we are checking. + * @param temp Pointer to buffer originally set as pszText field + * @param freeTemp True if we should free temp, false is we should not + * + * @remarks When doing a ListView_GetItem() MSDN says that the programmer + * should not rely on the pszText field pointing to the same buffer on + * return, that the list-view may change the pointer to point to the + * new text rather than place it in the buffer. + * + * For certain, if the mask for the ListView_GetItem() contains + * LVIF_NORECOMPUTE, then pszText is changed to LPSTR_TEXTCALLBACK. + * This function checks for that. I've never seen the pointer changed + * to 'new text' but we check for that also, and NULL. + * + * @assumes That temp is pointing to a buffer at least LVITEM_TEXT_MAX + 1 in + * size. All buffers being allocated for pszText in our code are + * that size. Do not call this function if the size of temp is + * unknown, or less than LVITEM_TEXT_MAX + 1 in size. + */ +static void checkForCallBack(LPLVITEM lvi, char *temp, bool freeTemp) +{ + if ( lvi->pszText != temp ) + { + if ( lvi->pszText == LPSTR_TEXTCALLBACK || lvi->pszText == NULL ) + { + lvi->cchTextMax = 0; + if ( freeTemp ) + { + LocalFree(temp); + } + } + else + { + StrCpyN(temp, lvi->pszText, LVITEM_TEXT_MAX); + temp[LVITEM_TEXT_MAX] = '\0'; + + lvi->cchTextMax = LVITEM_TEXT_MAX + 1; + lvi->pszText = temp; + } + } +} + +/** * Allocates memory for the text buffer in a list-view item structure. * * This should only be used for Rexx objects such as a LvItem or LvSubItem, @@ -339,10 +397,14 @@ return false; } - safeLocalFree(pLVI->pszText); - pLVI->pszText = pszText; + if ( pLVI->pszText != LPSTR_TEXTCALLBACK ) + { + safeLocalFree(pLVI->pszText); + } pLVI->cchTextMax = (LVITEM_TEXT_MAX + 1); + pLVI->pszText = pszText; + return true; } @@ -566,31 +628,111 @@ * @remarks If a memory allocation error happens, we raise an exception, but * leave the current text alone. No errors are reported. * - * If subitem is out of bounds then we just do nothing. + * If subitem is out of bounds then we just do nothing. We need to + * account for LPSTR_TEXTCALLBACK. */ static void updateFullRowText(RexxMethodContext *c, pCLvFullRow pclvfr, uint32_t subitem, CSTRING text) { if ( subitem <= pclvfr->subItemCount ) { - size_t len = strlen(text) + 1; + size_t len = 0; + char *newText; - char *newText = (char *)LocalAlloc(LPTR, len); - if ( newText == NULL ) + if ( text == LPSTR_TEXTCALLBACK ) { - outOfMemoryException(c->threadContext); - return; + newText = LPSTR_TEXTCALLBACK; } - memcpy(newText, text, len); + else + { + len = strlen(text) + 1; + char *newText = (char *)LocalAlloc(LPTR, len); + if ( newText == NULL ) + { + outOfMemoryException(c->threadContext); + return; + } + memcpy(newText, text, len); + } + LPLVITEM lvi = pclvfr->subItems[subitem]; - safeLocalFree(lvi->pszText); + if ( lvi->pszText != LPSTR_TEXTCALLBACK ) + { + safeLocalFree(lvi->pszText); + } + lvi->pszText = newText; lvi->cchTextMax = (int)len; } } /** + * Checks if the user data for a list-view item has bee set to a LvFullRow + * object. + * + * @param hList + * @param itemIndex + * + * @return The CSelf struct for a LvFullRow object if the user data of the + * list-view item has been set to a LvFullRow object, otherwise null. + * + * @note The item indexes in the full row struct are updated if the full row + * object is found. + */ +static pCLvFullRow maybeGetFullRow(HWND hList, uint32_t itemIndex) +{ + LVITEM lvi = {LVIF_PARAM, itemIndex}; + pCLvFullRow pclvfr = NULL; + + if ( ListView_GetItem(hList, &lvi) != 0 ) + { + if ( isLvFullRowStruct((void *)(lvi.lParam)) ) + { + pclvfr = (pCLvFullRow)lvi.lParam; + updateFullRowIndexes(pclvfr); + } + } + return pclvfr; +} + +static bool reasonableColumnFix(RexxMethodContext *c, HWND hList, uint32_t colIndex, bool removed) +{ + uint32_t cItems = ListView_GetItemCount(hList); + + if ( cItems == 0 ) + { + return false; + } + + for ( uint32_t i = 0; i < cItems, i < 3; i++ ) + { + char buff[128]; + + pCLvFullRow pclvfr = maybeGetFullRow(hList, i); + if ( pclvfr == NULL ) + { + _snprintf(buff, sizeof(buff), "the item data of list-view item %d is not a LvFullRow object", i); + + executionErrorException(c->threadContext, buff); + return false; + } + + if ( ! validColumnIndex(pclvfr, removed, colIndex) ) + { + _snprintf(buff, sizeof(buff), + "LvFullRow object at list-view item %d; invalid column %s (subitem columns=%d column=%d)", + i, removed ? "delete" : "insert", pclvfr->subItemCount, colIndex); + + executionErrorException(c->threadContext, buff); + return false; + } + } + + return true; +} + +/** * Each item in a list-view allows the user to store a value at the lParam * member of the LVITEM struct. * @@ -843,7 +985,7 @@ * to insert the item with the groupId set to 0, the insert fails. * * I don't know if this is because groups are not available or what. - * For new, we check for a 0 value and change it to I_GROUPIDNONE. + * For now, we check for a 0 value and change it to I_GROUPIDNONE. */ static RexxObjectPtr newLvItem(RexxMethodContext *c, HWND hList, uint32_t itemIndex) { @@ -868,6 +1010,8 @@ lvi->stateMask = (uint32_t)-1; lvi->mask = LVITEM_ALL_MASK; + char *temp = lvi->pszText; + if ( ! ListView_GetItem(hList, lvi) ) { goto err_out; @@ -876,6 +1020,7 @@ { lvi->iGroupId = I_GROUPIDNONE; } + checkForCallBack(lvi, temp, true); RexxClassObject rxLvI = rxGetContextClass(c, "LVITEM"); if ( rxLvI == NULLOBJECT ) @@ -939,13 +1084,15 @@ goto done_out; } - lvi->mask = LVIF_TEXT | LVIF_IMAGE; + char *temp = lvi->pszText; + lvi->mask = LVIF_TEXT | LVIF_IMAGE | LVIF_NORECOMPUTE; if ( ! ListView_GetItem(hList, lvi) ) { safeLocalFree(lvi->pszText); goto done_out; } + checkForCallBack(lvi, temp, true); RexxClassObject rxLvSi = rxGetContextClass(c, "LVSUBITEM"); if ( rxLvSi == NULLOBJECT ) @@ -963,34 +1110,68 @@ } /** - * Checks if the user data for a list-view item has bee set to a LvFullRow - * object. + * Iterates through all LvFullRow objects assigned as the item data of a + * list-view item and adds or removes the specified subitem column. * + * @param c * @param hList - * @param itemIndex + * @param colIndex + * @param removed * - * @return The CSelf struct for a LvFullRow object if the user data of the - * list-view item has been set to a LvFullRow object, otherwise null. + * @return The true or false object. * - * @note The item indexes in the full row struct are updated if the full row - * object is found. + * @remarks Theoretically this should only be invoked when all list-view items + * have a full row object assigned as the item data for the item, and + * the column index is valid for all full rows. We check for this, + * but allow a few errors before we quit. + * + * But, even one error indicates the user has something screwed up, so + * I'm not sure that we shouldn't be rasing an error condition ... */ -static pCLvFullRow maybeGetFullRow(HWND hList, uint32_t itemIndex) +static RexxObjectPtr fixColumns(RexxMethodContext *c, HWND hList, uint32_t colIndex, bool removed) { - LVITEM lvi = {LVIF_PARAM, itemIndex}; - pCLvFullRow pclvfr = NULL; + uint32_t cItems = ListView_GetItemCount(hList); + uint32_t cErrs = 0; + uint32_t i = 0; - if ( ListView_GetItem(hList, &lvi) != 0 ) + for ( i = 0; i < cItems && cErrs < 3; i++ ) { - if ( isLvFullRowStruct((void *)(lvi.lParam)) ) + pCLvFullRow pclvfr = maybeGetFullRow(hList, i); + if ( pclvfr == NULL ) { - pclvfr = (pCLvFullRow)lvi.lParam; - updateFullRowIndexes(pclvfr); + cErrs++; + continue; } + + if ( ! validColumnIndex(pclvfr, removed, colIndex) ) + { + cErrs++; + continue; + } + + if ( removed ) + { + removeSubItemFromRow(c, pclvfr, colIndex); + } + else + { + RexxObjectPtr lvSubItem = newLvSubitem(c, hList, i, colIndex); + if ( lvSubItem == TheNilObj ) + { + break; + } + + if ( ! insertSubItemIntoRow(c, lvSubItem, pclvfr, colIndex) ) + { + break; + } + } } - return pclvfr; + + return (i == cItems ? TheTrueObj : TheFalseObj); } + /** * Adds an item to the list view using a LvFullRow object. The item is * inserted, appended, or prepended to the list, as specified by the FullRowOp @@ -1690,13 +1871,28 @@ * * @param index [required] The zero-based index of the column to delete * + * @param adjustFullRows [optional] If true attempts to fix up the LvFullRow + * objects assigned to the item data of each list-view + * item. Does nothing if false. The default is false. + * * @return 0 on success, 1 on error. * - * @notes Column 0 can not be deleted. If column 0 must be deleted, MSDN - * suggests inserting a dummy column at index 0 and then deleting + * @notes MSDN says column 0 can not be deleted. If column 0 must be deleted, + * MSDN suggests inserting a dummy column at index 0 and then deleting * column 1. + * + * However, this is not true, column 0 can be deleted. What can not be + * deleted is the list-view item information for column 0. When a + * column for a subitem is deleted, the subitem information is deleted. + * But, when column 0 is deleted the item inforation is not deleted. + * + * Only adjust the LvFullRow objects if every list-view item has a + * LvFullRow item assigned as the item data, and the programmer has + * kept the LVFullRows consistent with changes to the column count of + * this list-view. If these conditions are not met, this method will + * return an error, even if the column was deleted successfully. */ -RexxMethod2(RexxObjectPtr, lv_deleteColumn, uint32_t, index, CSELF, pCSelf) +RexxMethod3(RexxObjectPtr, lv_deleteColumn, uint32_t, index, OPTIONAL_logical_t, adjustFullRows, CSELF, pCSelf) { pCDialogControl pcdc = validateDCCSelf(context, pCSelf); if ( pcdc == NULL ) @@ -1704,7 +1900,25 @@ return TheOneObj; } - return ListView_DeleteColumn(pcdc->hCtrl, index) ? TheZeroObj : TheOneObj; + RexxObjectPtr result = ListView_DeleteColumn(pcdc->hCtrl, index) ? TheZeroObj : TheOneObj; + + if ( result == TheZeroObj && index > 0 && adjustFullRows ) + { + if ( ! reasonableColumnFix(context, pcdc->hCtrl, index, true) ) + { + context->ClearCondition(); + result = TheOneObj; + } + else + { + if ( fixColumns(context, pcdc->hCtrl, index, true) == TheFalseObj ) + { + result = TheOneObj; + } + } + } + + return result; } /** ListView::deselectAll() @@ -1830,6 +2044,63 @@ return -1; } + +/** ListView::fixFullRowColumns() + * + * + */ +RexxMethod3(RexxObjectPtr, lv_fixFullRowColumns, uint32_t, colIndex, logical_t, removed, CSELF, pCSelf) +{ + RexxObjectPtr result = TheFalseObj; + + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) + { + goto done_out; + } + + bool isRemove = removed ? true : false; + uint32_t cColumns = (uint32_t)getColumnCount(pcdc->hCtrl); + if ( cColumns == (uint32_t)-1 ) + { + severeErrorException(context->threadContext, "the list-view control reports it has no columns; can not continue"); + goto done_out; + } + + if ( colIndex == 0 ) + { + userDefinedMsgException(context->threadContext, 2, "can not be column 0"); + goto done_out; + } + + if ( isRemove ) + { + if ( colIndex > cColumns ) + { + wrongRangeException(context->threadContext, 2, 1, cColumns, colIndex); + goto done_out; + } + } + else + { + if ( colIndex >= cColumns ) + { + wrongRangeException(context->threadContext, 2, 1, cColumns - 1, colIndex); + goto done_out; + } + } + + if ( ! reasonableColumnFix(context, pcdc->hCtrl, colIndex, isRemove) ) + { + goto done_out; + } + + result = fixColumns(context, pcdc->hCtrl, colIndex, isRemove); + +done_out: + return result; +} + /** ListView::getCheck() * * @@ -2186,7 +2457,8 @@ * * @param _item [required] Can be a LvItem object or the item index. * - * If it is a LvItem, we just fill it in. + * If it is a LvItem, we just do ListView_GetItem() to fill it in + * as specified. * * If it is an index and we have no LvFullRow, we return a new, * instantiated, LvItem object that reflects the item and the @@ -2197,6 +2469,20 @@ * current transitory state, and then return the Rexx LvItem from * the full row. * + * @return When _item is a LvItem object, returns true on success and false on + * error. + * + * When the item to get is specified as an index, returns a LvItem + * object on success, or the .nil object on error. + * + * @notes If _item is a LvItem, some, or all, of the information the list-view + * maintains on the item is returned by the attributes of the LvItem. + * The mask attribute of the LvItem specifies which attributes are set + * to the current information of the item. + * + * If _item is the item index, then the attributes of the returned + * LvItem object are all set to reflect the current state of the item. + * * @remarks If we have a LvFullRow object assigned to the user data, we use * the Rexx item in the full row. maybeGetFullRow() will update the item * index, and then updateFullRowItemState will sync the LVITEM struct by doing @@ -2210,12 +2496,21 @@ if ( context->IsOfType(_item, "LVITEM") ) { - LPLVITEM plvi = (LPLVITEM)context->ObjectToCSelf(_item); + LPLVITEM plvi = (LPLVITEM)context->ObjectToCSelf(_item); + char *temp = plvi->pszText; BOOL success = ListView_GetItem(hList, plvi); - if ( success && (plvi->mask & LVIF_GROUPID) && plvi->iGroupId == 0 ) + if ( success ) { - plvi->iGroupId = I_GROUPIDNONE; + if ( (plvi->mask & LVIF_GROUPID) && plvi->iGroupId == 0 ) + { + plvi->iGroupId = I_GROUPIDNONE; + } + + if ( (plvi->mask & LVIF_TEXT) && temp != NULL && plvi->cchTextMax == LVITEM_TEXT_MAX + 1 ) + { + checkForCallBack(plvi, temp, true); + } } return success ? TheTrueObj : TheFalseObj; @@ -2293,7 +2588,7 @@ HWND hList = getDChCtrl(pCSelf); LVITEM lvi = {0}; - char buf[256]; + char buf[LVITEM_TEXT_MAX + 1]; bool subitemImages = hasSubitemImages(hList); @@ -2301,7 +2596,7 @@ lvi.iSubItem = subItem; lvi.mask = LVIF_TEXT; lvi.pszText = buf; - lvi.cchTextMax = 255; + lvi.cchTextMax = LVITEM_TEXT_MAX + 1; if ( subItem == 0 ) { @@ -2321,9 +2616,18 @@ return TheFalseObj; } + checkForCallBack(&lvi, buf, false); + // Set the text index now because we are going to reuse the buffer for the // state text. - context->DirectoryPut(d, context->String(lvi.pszText), "TEXT"); + if ( lvi.pszText == LPSTR_TEXTCALLBACK ) + { + context->DirectoryPut(d, context->String(LPSTR_TEXTCALLBACK_STRING), "TEXT"); + } + else + { + context->DirectoryPut(d, context->String(lvi.pszText), "TEXT"); + } *buf = '\0'; RexxObjectPtr itemData = TheNilObj; @@ -2372,28 +2676,114 @@ /** ListView::getSubitem() * - * Returns a LvSubItem object for the item and subitem indexes specified. + * Returns, or fills in, a LvSubItem object for the subitem specified. * + * @param _item [required] Can be a LvSubItem object or the item index. + * + * If it is a LvSubItem, we just do ListView_GetItem() to fill it + * in as specified. + * + * If it is an index and we have no LvFullRow, we return a new, + * instantiated, LvSubItem object that reflects the item and the + * item's current state. + * + * If we do have a LvFullRow, we ensure the LvFullRow objects + * have the item indexes in sync, and then return the Rexx + * LvSubItem from the full row. + * + * @return When _item is a LvSubItem object, returns true on success and false + * on error. + * + * When the subitem to get is specified as an index, returns a + * LvSubItem object on success, or the .nil object on error. + * + * @notes If _item is a LvSubItem, some, or all, of the information the + * list-view maintains on the item is returned by the attributes of the + * LvSubItem. The mask attribute of the LvSubItem specifies which + * attributes are set to the current information of the item. + * + * If _item is the item index, then the attributes of the returned + * LvSubItem object are all set to reflect the current state of the + * subitem. + * + * All list-view items have the same number of subitems. The number of + * subitems depends on the number of columns the list-view has. If the + * index of the subitem is not valid, this method will fail. + * * @remarks The ListView_GetItem macro will not fail, even if the subitem - * index is greater than any existing subitem. - * string. Plus, there is no reason that the user could not have - * added subitems, but the list-view is not in report view. So, we - * don't check subitemIndex with getColumnCount() + * index is greater than any existing subitem. So, we check the + * subitemIndex with getColumnCount() and fail the method if it is + * not valid. + * + * If we have a LvFullRow object assigned to the user data, we use + * the Rexx subitem in the full row, if it exists. maybeGetFullRow() + * will update the item index, which will ensure things are correct. + * + * NOTE: remarks from getItemInfo() we need to test what happens here + * + * @remarks ListView_GetItem() returns some bogus information if a subitem + * index is used. For example, if the list-view does not have the + * SUBITEMIMAGES extended style, it does not update the iImage field. + * Subitems can not have a state, but values for the item state are + * returned. + * + * So, if the user specifies a subitem index we adjust the return to + * be correct. For a subitem, state is always the empty string, + * image is always -1 if the SUBITEMIMAGES style is absent, itemData + * is always .nil */ -RexxMethod3(RexxObjectPtr, lv_getSubitem, uint32_t, itemIndex, uint32_t, subitemIndex, CSELF, pCSelf) +RexxMethod3(RexxObjectPtr, lv_getSubitem, RexxObjectPtr, _item, OPTIONAL_uint32_t, subitemIndex, CSELF, pCSelf) { RexxObjectPtr result = TheNilObj; - HWND hList = getDChCtrl(pCSelf); - if ( subitemIndex == 0 ) + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + if ( pcdc == NULL ) { goto done_out; } - // If we have a LvFullRow object assigned to the user data, we use the Rexx - // subitem in the full row, if it exists. maybeGetFullRow() will update the - // item index, which will ensure things are correct. + HWND hList = pcdc->hCtrl; + int32_t count = getColumnCount(hList); + if ( context->IsOfType(_item, "LVSUBITEM") ) + { + LPLVITEM plvi = (LPLVITEM)context->ObjectToCSelf(_item); + + if ( count == -1 || plvi->iSubItem == 0 || plvi->iSubItem >= count ) + { + result = TheFalseObj; + goto done_out; + } + + char *temp = plvi->pszText; + + result = ListView_GetItem(hList, plvi) ? TheTrueObj : TheFalseObj; + + if ( result == TheTrueObj && (plvi->mask & LVIF_TEXT) && temp != NULL && plvi->cchTextMax == LVITEM_TEXT_MAX + 1 ) + { + checkForCallBack(plvi, temp, true); + } + + goto done_out; + } + + uint32_t itemIndex; + if ( ! context->UnsignedInt32(_item, &itemIndex) ) + { + wrongArgValueException(context->threadContext, 1, "a LvSubItem object or valid item index", _item); + goto done_out; + } + if ( argumentOmitted(2) ) + { + missingArgException(context->threadContext, 2); + goto done_out; + } + + if ( count < 1 || subitemIndex == 0 || subitemIndex >= (uint32_t)count ) + { + goto done_out; + } + pCLvFullRow pclvfr = maybeGetFullRow(hList, itemIndex); if ( pclvfr != NULL ) { @@ -2659,19 +3049,29 @@ * @param text * @param width The width of the column in pixels * + * @param adjustFullRows [optional] If true attempts to fix up the LvFullRow + * objects assigned to the item data of each list-view + * item. Does nothing if false. The default is false. * - * @note Even though the width argument in insertColumn() was documented as - * being in pixels, the code actually converted it to dialog units. - * This method is provided to really use pixels. * + * @note Only adjust the LvFullRow objects if every list-view item has a + * LvFullRow item assigned as the item data, and the programmer has + * kept the LVFullRows consistent with changes to the column count of + * this list-view. If these conditions are not met, this method will + * return an error, even if the column was deleted successfully. + * + * @remarks Even though the width argument in insertColumn() was documented as + * being in pixels, the code actually converted it to dialog units. + * This method is provided to really use pixels. + * * @remarks Not sure why there is a restriction on the length of the column * label, or why the passed text is copied to a buffer. The * ListView_InsertColumn() API does not impose a limit on the length, * and just asks for a pointer to a string. Both the length * restriction and the copy are probably not needed. */ -RexxMethod5(int, lv_insertColumnPx, OPTIONAL_uint16_t, column, CSTRING, text, uint16_t, width, - OPTIONAL_CSTRING, fmt, CSELF, pCSelf) +RexxMethod6(int, lv_insertColumnPx, OPTIONAL_uint16_t, column, CSTRING, text, uint16_t, width, + OPTIONAL_CSTRING, fmt, OPTIONAL_logical_t, adjustFullRows, CSELF, pCSelf) { HWND hwnd = getDChCtrl(pCSelf); @@ -2720,6 +3120,24 @@ ListView_InsertColumn(hwnd, lvi.iSubItem, &lvi); ListView_DeleteColumn(hwnd, 0); } + + if ( retVal > 0 && adjustFullRows ) + { + // retVal is the inserted column indext + if ( ! reasonableColumnFix(context, hwnd, retVal, false) ) + { + context->ClearCondition(); + retVal = -1; + } + else + { + if ( fixColumns(context, hwnd, retVal, false) == TheFalseObj ) + { + retVal = -1; + } + } + } + return retVal; } @@ -2962,28 +3380,62 @@ if ( oldUserData != TheNilObj ) { - if ( pclvfr == NULL ) + if ( lParamIsModified ) { - if ( lParamIsModified ) - { - unProtectControlUserData(context, pcdc, oldUserData); - } + unProtectControlUserData(context, pcdc, oldUserData); } - else + else if ( pclvfr != NULL ) { - if ( lParamIsModified ) + mergeLviState(context, pclvfr, pclvfr->subItems[0], lvi); + } + } + + return TRUE; + +err_out: + return FALSE; +} + +/** ListView::modifySubitem() + * + * + */ +RexxMethod2(logical_t, lv_modifySubitem, RexxObjectPtr, lvSubItem, CSELF, pCSelf) +{ + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + + if ( pcdc == NULL ) + { + goto err_out; + } + + if ( ! context->IsOfType(lvSubItem, "LVSUBITEM") ) + { + wrongClassException(context->threadContext, 1, "LvSubItem"); + goto err_out; + } + + LPLVITEM lvi = (LPLVITEM)context->ObjectToCSelf(lvSubItem); + + if ( ListView_SetItem(pcdc->hCtrl, lvi) ) + { + pCLvFullRow pclvfr = maybeGetFullRow(pcdc->hCtrl, lvi->iItem); + + if ( pclvfr != NULL && pclvfr->subItemCount >= (uint32_t)lvi->iSubItem ) + { + if ( lvi->mask & LVIF_TEXT ) { - unProtectControlUserData(context, pcdc, oldUserData); + updateFullRowText(context, pclvfr, lvi->iSubItem, lvi->pszText); } - else + + if ( lvi->mask & LVIF_IMAGE ) { - mergeLviState(context, pclvfr, pclvfr->subItems[0], lvi); + pclvfr->subItems[lvi->iSubItem]->iImage = lvi->iImage; } } + return TRUE; } - return TRUE; - err_out: return FALSE; } @@ -3597,6 +4049,9 @@ */ RexxMethod3(RexxObjectPtr, lv_zTest, uint32_t, itemIndex, uint32_t, subItemIndex, CSELF, pCSelf) { + printf("zTest() no test at this time\n"); + +#if 0 printf("zTest() itemIndex=%d subItemIndex=%d\n", itemIndex, subItemIndex); pCDialogControl pcdc = validateDCCSelf(context, pCSelf); @@ -3605,6 +4060,20 @@ return TheFalseObj; } + uint32_t count = ListView_GetItemCount(pcdc->hCtrl); + for ( uint32_t i = 0; i < count; i++ ) + { + pCLvFullRow pclvfr = maybeGetFullRow(pcdc->hCtrl, i); + printf("Item=%d subitem count=%d\n", i, pclvfr->subItemCount); + + for ( uint32_t j = 1; j <= pclvfr->subItemCount; j++ ) + { + printf(" subitem=%d\n imageIndex=%d\n cchTextMax=%d\n text=%s\n", j, pclvfr->subItems[j]->iImage, + pclvfr->subItems[j]->cchTextMax, + pclvfr->subItems[j]->pszText == LPSTR_TEXTCALLBACK ? "textCallBack" : pclvfr->subItems[j]->pszText); + } + } + /* LVCOLUMN lvc = { 0 }; lvc.mask = LVCF_WIDTH | LVCF_SUBITEM; @@ -3618,7 +4087,7 @@ } */ - + /* LVITEM lvi = { 0 }; lvi.iItem = itemIndex; lvi.iSubItem = subItemIndex; @@ -3630,6 +4099,8 @@ lvi.cchTextMax = 1024; printf("pszText=%p\n", lvi.pszText); + */ + /* if ( ListView_GetItem(pcdc->hCtrl, &lvi) ) { @@ -3646,6 +4117,7 @@ } */ + /* if ( ListView_SetItem(pcdc->hCtrl, &lvi) ) { printf("ListView_SetItem() returns TRUE\n"); @@ -3654,6 +4126,8 @@ { printf("ListView_SetItem() returns FALSE\n"); } + */ +#endif return TheTrueObj; } @@ -3866,7 +4340,7 @@ } else if ( pLVI->pszText == LPSTR_TEXTCALLBACK ) { - return c->String("lpStrTextCallBack"); + return c->String(LPSTR_TEXTCALLBACK_STRING); } return c->String(pLVI->pszText); @@ -4214,7 +4688,7 @@ * retrieved or modified. The keyword ALL can be used * to specify all state values. * - * @remarks In general, if the LvItem object is going to be used to set an + * @notes In general, if the LvItem object is going to be used to set an * item, the user does not need to specify the mask value, the proper * mask is created depending on what attributes the user assigned * values to. I.e., if the user assigns some text to the text @@ -4229,18 +4703,32 @@ * columnFormats, and groupIndex attributes are set through their * attribute methods. * - * @notes We allow a new LvItem to be instantiated internally by allocating + * @remarks We allow a new LvItem to be instantiated internally by allocating * the CSelf buffer for the object and passing it in as the first * argument. We check for this by checking if the first argument is * a Rexx buffer object and the second argument is the "magic" string * value. * - * Although not implemented yet, we plan on adding a getItem() method - * that will take a LvItem object as input. The user could then set - * the mask to specify what information is to be gotten. Because of - * this, if the text argument is omitted, we need to check the mask - * and set up a buffer to recieve the text if LVIF_TEXT is specified. + * The getItem() method will take a LvItem object as input. The user + * can then set the mask to specify what information is to be gotten. + * Because of this, if the text argument is omitted, we need to check + * the mask and set up a buffer to recieve the text if LVIF_TEXT is + * specified. The same thing applies to columns and colFormat + * attributes, we need to allocate the buffers to receive the + * inofmation * + * We have one problem. If the user is constucting this LvItem to + * receive information we would like to not set any attriubtes, allow + * them to be filled in as specified by the mask. But, if the user + * is constructing this LvItem to set the item and just omits the + * imageIndex arg, we would like to set imageIndex to I_IMAGENONE. + * Same thing applies to the group ID. + * + * But, we don't know what the user's intent is ... so, for now we + * are setting the image index to I_IMAGENONE if the imageIndex arg + * is omitted and the group ID to I_GROUPIDNONE if the groupID arg is + * omitted.. + * * The 'itemState' argument - Although the item state member in the * LVITEM struct is a single value for the state, the overlay image * index, and the state image index, we use this arg only for the @@ -4277,12 +4765,7 @@ // object is going to be used to retrieve information. if ( argumentExists(5) ) { - uint32_t flags = keyword2lvif(mask); - if ( flags == (uint32_t)-1 ) - { - return NULLOBJECT; - } - lvi->mask = flags; + lvi->mask = keyword2lvif(mask); } if ( argumentExists(1) ) @@ -4631,6 +5114,20 @@ /** LvSubItem::init() * * + * + * @remarks We check if the user is setting the mask, and what values he sets, + * first. This allows use to allocate the needed text buffer if the + * LvSubItem object is going to be used to retrieve information. + * + * We have one problem. If the user is constucting this LvSubItem to + * receive information we would like to not set any attriubtes, allow + * them to be filled in as specified by the mask. But, if the user + * is constructing this LvSubItem to set the item and just omits the + * imageIndex arg, we would like to set imageIndex to I_IMAGENONE. + * + * But, we don't know what the user's intent is ... so, for now we + * are setting the image index to I_IMAGENONE if the imageIndex arg + * is omitted. */ RexxMethod5(RexxObjectPtr, lvsi_init, RexxObjectPtr, _item, uint32_t, subItem, OPTIONAL_CSTRING, text, OPTIONAL_int32_t, imageIndex, OPTIONAL_CSTRING, mask) @@ -4654,30 +5151,48 @@ wrongRangeException(context->threadContext, 1, 0, INT_MAX, _item); return NULLOBJECT; } + if ( subItem == 0 ) + { + wrongRangeException(context->threadContext, 2, 1, INT_MAX, subItem); + return NULLOBJECT; + } lvi->iItem = item; lvi->iSubItem = subItem; - if ( ! argumentExists(3) ) + if ( argumentExists(5) ) { - // Sending setLviText the empty string will cause it to set up the - // buffer to receive information. - text = ""; + lvi->mask = keyword2lvifSub(mask); } - if ( ! setLviText(context, lvi, text, 3) ) + + if ( argumentExists(3) ) { - return NULLOBJECT; + if ( ! setLviText(context, lvi, text, 3) ) + { + return NULLOBJECT; + } } + else + { + // Check if the user has set the LVIF_TEXT flag. + if ( lvi->mask & LVIF_TEXT ) + { + // The empty string tells setLviText() to allocate a buffer. + if ( ! setLviText(context, lvi, "", 3) ) + { + return NULLOBJECT; + } + } + } + lvi->mask |= LVIF_IMAGE; if ( argumentExists(4) ) { lvi->iImage = imageIndex < I_IMAGENONE ? I_IMAGENONE : imageIndex; - lvi->mask |= LVIF_IMAGE; } - - if ( argumentExists(5) ) + else { - lvi->mask = keyword2lvifSub(mask); + lvi->iImage = I_IMAGENONE; } return NULLOBJECT; @@ -4771,6 +5286,39 @@ } /** + * Checks that a subitem column being added or removed from a full row stuct is + * valid. + * + * A column that does not exist already in the struct can not be removed. A + * column being added or inserted can not result is a sparse array. + * + * + * @param pclvfr + * @param colIndex + * + * @return bool + */ +static bool validColumnIndex(pCLvFullRow pclvfr, bool removed, uint32_t colIndex) +{ + if ( removed ) + { + if ( colIndex > pclvfr->subItemCount ) + { + return false; + } + } + else + { + if ( colIndex > pclvfr->subItemCount + 1 ) + { + return false; + } + } + + return true; +} + +/** * For a LvFullRow object, we put the Rexx item and subitems in a Rexx bag and * save the bag as an object variable to prevent GC of the items. * @@ -4829,6 +5377,106 @@ return true; } +/** + * Removes a subitem column from the full row struct. + * + * @param c + * @param pclvfr + * @param index + * + * @return RexxObjectPtr + * + * @assumes That updateFullRowIndexes() has already been called to ensure that + * the item indexes in the current row are correct. + * + * That index is valid for the full row, i.e., it must be an existing + * column in the full row. + */ +static RexxObjectPtr removeSubItemFromRow(RexxMethodContext *c, pCLvFullRow pclvfr, uint32_t index) +{ + RexxObjectPtr subItem = pclvfr->rxSubItems[index]; + + if ( index < pclvfr->subItemCount ) + { + size_t count = (pclvfr->subItemCount - index) * sizeof(void *); + + memmove(&pclvfr->rxSubItems[index], &pclvfr->rxSubItems[index + 1], count); + memmove(&pclvfr->subItems[index], &pclvfr->subItems[index + 1], count); + } + + pclvfr->subItemCount--; + + adjustSubItemIndexes(pclvfr); + + return lvfrUnStoreItem(c, pclvfr, subItem); +} + + +/** + * Inserts the specified LvSubItem into a LvFullRow object. + * + * @param c + * @param lvSubitem + * @param pclvfr + * @param index + * + * @return true on success, false on error. + * + * @assumes updateFullRowIndexes() has already been called to ensure that the + * item indexes in the current row are correct. + * + * That the index is within the bounds of the current subitems array, + * plus one. I.e., the subitem can be appended to the current array, + * but it can not be added such that the array becomes sparse. + * + * If the current subitem array has 4 subitems, the subitem can be + * 'inserted' as the 5th subitem, but not as the 6th or greate subitem. + * + * @remarks The subitem arrays are expanded if needed. The subitem indexes of + * all the subitems are adjusted for the insertion. + */ +static RexxObjectPtr insertSubItemIntoRow(RexxMethodContext *c, RexxObjectPtr lvSubitem, pCLvFullRow pclvfr, uint32_t index) +{ + uint32_t i = pclvfr->subItemCount + 1; + + // Be sure we have room in the arrays for the new column. + if ( i >= pclvfr->size ) + { + if ( ! expandSubItems(c, pclvfr) ) + { + return TheFalseObj; + } + } + + // If the new column is not being appended, then we need to shift the + // exising columns up one slot. + if ( index < i ) + { + size_t count = (pclvfr->subItemCount - index + 1) * sizeof(void *); + + memmove(&pclvfr->rxSubItems[index + 1], &pclvfr->rxSubItems[index], count); + memmove(&pclvfr->subItems[index + 1], &pclvfr->subItems[index], count); + } + + // Add the new subitem at its column + pclvfr->subItemCount = i; + pclvfr->rxSubItems[index] = lvSubitem; + pclvfr->subItems[index] = (LPLVITEM)c->ObjectToCSelf(lvSubitem); + pclvfr->subItems[index]->iItem = pclvfr->subItems[0]->iItem; + + // Adjust the subitem indexes from the new subitem to the end of columns + for ( uint32_t j = index; j <= i; j++) + { + pclvfr->subItems[j]->iSubItem = j; + } + + // Protect the new subitem from GC. + lvfrStoreItem(c, pclvfr, index); + + return TheTrueObj; +} + + /** LvFullRow::uninit() * */ @@ -5020,27 +5668,61 @@ return 0; } - uint32_t i = pclvfr->subItemCount + 1; + updateFullRowIndexes(pclvfr); - if ( i >= pclvfr->size ) + uint32_t newColumn = pclvfr->subItemCount + 1; + if ( ! insertSubItemIntoRow(context, subitem, pclvfr, newColumn) ) { - if ( ! expandSubItems(context, pclvfr) ) - { - return 0; - } + return 0; } + return newColumn; +} + +/** LvFullRow::insertSubitem() + * + * Inserts a new subitem into this full row and adjusts the subitem indexes for + * all existing subitems when needed. + * + * @param subitem The subitem to insert. + * + * @param colIndex The insertion index for the subitem. + * + * @return True on success, false on error. + */ +RexxMethod3(RexxObjectPtr, lvfr_insertSubitem, RexxObjectPtr, subitem, uint32_t, colIndex, CSELF, pCSelf) +{ + RexxObjectPtr result = TheFalseObj; + + pCLvFullRow pclvfr = (pCLvFullRow)pCSelf; + + if ( ! context->IsOfType(subitem, "LVSUBITEM") ) + { + wrongClassException(context->threadContext, 1, "LvSubItem"); + goto done_out; + } + + if ( colIndex == 0 ) + { + userDefinedMsgException(context->threadContext, 2, "can not be column 0"); + goto done_out; + } + + if ( colIndex > pclvfr->subItemCount + 1 ) + { + wrongRangeException(context, 2, 1, pclvfr->subItemCount + 1, colIndex); + goto done_out; + } + updateFullRowIndexes(pclvfr); - pclvfr->subItemCount = i; - pclvfr->rxSubItems[i] = subitem; - pclvfr->subItems[i] = (LPLVITEM)context->ObjectToCSelf(subitem); - pclvfr->subItems[i]->iSubItem = i; - pclvfr->subItems[i]->iItem = pclvfr->subItems[0]->iItem; + if ( insertSubItemIntoRow(context, subitem, pclvfr, colIndex) ) + { + result = TheTrueObj; + } - lvfrStoreItem(context, pclvfr, i); - - return i; +done_out: + return result; } /** LvFullRow::item() @@ -5078,23 +5760,7 @@ } updateFullRowIndexes(pclvfr); - RexxObjectPtr subItem = pclvfr->rxSubItems[index]; - - if ( index < pclvfr->subItemCount ) - { - size_t count = (pclvfr->subItemCount - index) * sizeof(void *); - - memmove(&pclvfr->rxSubItems[index], &pclvfr->rxSubItems[index + 1], count); - memmove(&pclvfr->subItems[index], &pclvfr->subItems[index + 1], count); - } - - pclvfr->subItemCount--; - - adjustSubItemIndexes(pclvfr); - - subItem = lvfrUnStoreItem(context, pclvfr, subItem); - - return subItem; + return removeSubItemFromRow(context, pclvfr, index); } /** LvFullRow::subItem() Modified: ooDialog/trunk/ooDialog/oodPackageEntry.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-12-03 04:10:04 UTC (rev 8655) +++ ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-12-04 03:48:57 UTC (rev 8656) @@ -1012,6 +1012,7 @@ REXX_METHOD_PROTOTYPE(lv_deselectAll); REXX_METHOD_PROTOTYPE(lv_find); REXX_METHOD_PROTOTYPE(lv_findNearestXY); +REXX_METHOD_PROTOTYPE(lv_fixFullRowColumns); REXX_METHOD_PROTOTYPE(lv_getCheck); REXX_METHOD_PROTOTYPE(lv_getColor); REXX_METHOD_PROTOTYPE(lv_getColumnCount); @@ -1040,6 +1041,7 @@ REXX_METHOD_PROTOTYPE(lv_modify); REXX_METHOD_PROTOTYPE(lv_modifyColumnPx); REXX_METHOD_PROTOTYPE(lv_modifyItem); +REXX_METHOD_PROTOTYPE(lv_modifySubitem); REXX_METHOD_PROTOTYPE(lv_prependFullRow); REXX_METHOD_PROTOTYPE(lv_removeItemData); REXX_METHOD_PROTOTYPE(lv_replaceExtendStyle); @@ -1106,6 +1108,7 @@ REXX_METHOD_PROTOTYPE(lvfr_init); REXX_METHOD_PROTOTYPE(lvfr_unInit); REXX_METHOD_PROTOTYPE(lvfr_addSubitem); +REXX_METHOD_PROTOTYPE(lvfr_insertSubitem); REXX_METHOD_PROTOTYPE(lvfr_item); REXX_METHOD_PROTOTYPE(lvfr_removeSubitem); REXX_METHOD_PROTOTYPE(lvfr_subitem); @@ -2024,6 +2027,7 @@ REXX_METHOD(lv_deselectAll, lv_deselectAll), REXX_METHOD(lv_find, lv_find), REXX_METHOD(lv_findNearestXY, lv_findNearestXY), + REXX_METHOD(lv_fixFullRowColumns, lv_fixFullRowColumns), REXX_METHOD(lv_getCheck, lv_getCheck), REXX_METHOD(lv_getColor, lv_getColor), REXX_METHOD(lv_getColumnCount, lv_getColumnCount), @@ -2052,6 +2056,7 @@ REXX_METHOD(lv_modify, lv_modify), REXX_METHOD(lv_modifyColumnPx, lv_modifyColumnPx), REXX_METHOD(lv_modifyItem, lv_modifyItem), + REXX_METHOD(lv_modifySubitem, lv_modifySubitem), REXX_METHOD(lv_prependFullRow, lv_prependFullRow), REXX_METHOD(lv_removeItemData, lv_removeItemData), REXX_METHOD(lv_replaceExtendStyle, lv_replaceExtendStyle), @@ -2118,6 +2123,7 @@ REXX_METHOD(lvfr_init, lvfr_init), REXX_METHOD(lvfr_unInit, lvfr_unInit), REXX_METHOD(lvfr_addSubitem, lvfr_addSubitem), + REXX_METHOD(lvfr_insertSubitem, lvfr_insertSubitem), REXX_METHOD(lvfr_item, lvfr_item), REXX_METHOD(lvfr_removeSubitem, lvfr_removeSubitem), REXX_METHOD(lvfr_subitem, lvfr_subitem), |
From: <mie...@us...> - 2012-12-07 00:02:01
|
Revision: 8663 http://sourceforge.net/p/oorexx/code-0/8663 Author: miesfeld Date: 2012-12-07 00:01:57 +0000 (Fri, 07 Dec 2012) Log Message: ----------- Work on RFE doc: #478 ooDialog - List-view could use a way to work with a complete row See ticket [Feature-Requests:#478] Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/ooDialog/ListView.cls ooDialog/trunk/ooDialog/UtilityClasses.cls ooDialog/trunk/ooDialog/ooDialog.cpp ooDialog/trunk/ooDialog/oodListView.cpp ooDialog/trunk/ooDialog/oodUtilities.cpp Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-06 23:58:35 UTC (rev 8662) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-07 00:01:57 UTC (rev 8663) @@ -89,7 +89,11 @@ * #1146 Return code from ListView::deleteColumn() not as documented +* #1147 SingleSelection class +* #1149 Potential crash in ooDialog connectKeyPress() method + + Feature Requests in ooDialog: ----------------------------- @@ -164,7 +168,7 @@ List-view items can contain subitems. This is most apparent in the row view of a list-vies where the subitems are displayed in columns next to -the item. However, the subitems, once added to an item, are always +the item. However, the subitems, once added to an item, are always present, even if the list-view is in another view, such as icon view. The LvFullRow class represents the list-view item and all its subitems. @@ -209,6 +213,10 @@ New Methods: ------------ +In the PlainBaseDialog class: + +getTextSizeTitleBar() + In the DialogControl class: useVersion() @@ -223,6 +231,16 @@ setItemData() +New Attributes: +--------------- + +In the SM (system metrics) class: + +cxSize +cxSmIcon +cyMenu + + Enhanced Methods: ----------------- Modified: ooDialog/trunk/ooDialog/ListView.cls =================================================================== --- ooDialog/trunk/ooDialog/ListView.cls 2012-12-06 23:58:35 UTC (rev 8662) +++ ooDialog/trunk/ooDialog/ListView.cls 2012-12-07 00:01:57 UTC (rev 8663) @@ -283,7 +283,7 @@ return self~sendWinIntMsg(self~LVM_UPDATE, index, 0) == 0 -::method zTest unguarded external "LIBRARY oodialog lv_zTest" +::method zTest unguarded external "LIBRARY oodialog lv_zTest" -- internal use only -- DEPRECATED to end of Class ::method removeImages unguarded -- DEPRECATED Modified: ooDialog/trunk/ooDialog/UtilityClasses.cls =================================================================== --- ooDialog/trunk/ooDialog/UtilityClasses.cls 2012-12-06 23:58:35 UTC (rev 8662) +++ ooDialog/trunk/ooDialog/UtilityClasses.cls 2012-12-07 00:01:57 UTC (rev 8663) @@ -230,8 +230,8 @@ ::attribute mouseHoverTime set class external "LIBRARY oodialog spi_getMouseHoverTime_cls" ::attribute mouseHoverWidth get class external "LIBRARY oodialog spi_getMouseHoverWidth_cls" ::attribute mouseHoverWidth set class external "LIBRARY oodialog spi_getMouseHoverWidth_cls" -::attribute nonClientMetrics get class external "LIBRARY oodialog spi_getNonClientMetrics_cls" -::attribute nonClientMetrics set class external "LIBRARY oodialog spi_setNonClientMetrics_cls" +::attribute nonClientMetrics get class external "LIBRARY oodialog spi_getNonClientMetrics_cls" -- For 4.2.2 +::attribute nonClientMetrics set class external "LIBRARY oodialog spi_setNonClientMetrics_cls" -- For 4.2.2 ::attribute updateFlag get class external "LIBRARY oodialog spi_getUpdateFlag_cls" ::attribute updateFlag set class external "LIBRARY oodialog spi_setUpdateFlag_cls" @@ -255,7 +255,7 @@ ::attribute cyDrag get class external "LIBRARY oodialog sm_cyDrag_cls" ::attribute cyFixedFrame get class external "LIBRARY oodialog sm_cyFixedFrame_cls" ::attribute cyHscroll get class external "LIBRARY oodialog sm_cyHScroll_cls" -::attribute cyMenu get class external "LIBRARY oodialog sm_cyMenu_cls" -- Document in 4.2.1, not 4.2.0 +::attribute cyMenu get class external "LIBRARY oodialog sm_cyMenu_cls" ::attribute cyScreen get class external "LIBRARY oodialog sm_cyScreen_cls" ::attribute menuDropAlignment get class external "LIBRARY oodialog sm_menuDropAlignment_cls" @@ -1509,14 +1509,12 @@ return ret ::routine SingleSelection public - use arg msg, title, labels, data, lx, max - if arg(5,"o") = 1 then lx = 0 - if arg(6,"o") = 1 then max= 0 - num = labels~items - do i=1 to num + use strict arg msg, title, labels, preSel = 1, rbWidth = 0, max = 0 + + do i = 1 to labels~items lab.i = labels[i] end - dlg = .SingleSelection~new(msg, title, lab., data, lx, max) + dlg = .SingleSelection~new(msg, title, lab., preSel, rbWidth, max) res = dlg~execute drop dlg return res Modified: ooDialog/trunk/ooDialog/ooDialog.cpp =================================================================== --- ooDialog/trunk/ooDialog/ooDialog.cpp 2012-12-06 23:58:35 UTC (rev 8662) +++ ooDialog/trunk/ooDialog/ooDialog.cpp 2012-12-07 00:01:57 UTC (rev 8663) @@ -3785,10 +3785,10 @@ * and will return the dimensions as it does after the dialog is * created. * - * @remarks For GetWindowDC(), if the HWND passed to it is NULL, it returns a - * DC for the screen. This works fine for our needs. Testing shows - * the same dimensions are returned with a NULL HWND as with the - * created dialog's HWND. + * @remarks For GetWindowDC(), if the window handle passed to it is NULL, it + * returns a DC for the screen. This works fine for our needs. + * Testing shows the same dimensions are returned with a NULL window + * handle as with the actual dialog's window handle. */ RexxMethod2(RexxObjectPtr, pbdlg_getTextSizeTitleBar, CSTRING, text, CSELF, pCSelf) { Modified: ooDialog/trunk/ooDialog/oodListView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-06 23:58:35 UTC (rev 8662) +++ ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-07 00:01:57 UTC (rev 8663) @@ -1198,14 +1198,25 @@ * @remarks The LvItem object in the row has its item index updated to what is * actually assigned by the list view. * - * Likewise, the item index in the LvSubItem object is updated to the - * the item index. This updating is done before the subitem is set, so - * that it is always set correctly. + * Likewise, the item index in the LvSubItem object(s) is updated to + * the the item index. This updating is done before the subitem is + * set, so that it is always set correctly. * * If the operation is append or prepend, the item index in the LvItem * object is ignored. Instead it is set to an index that will ensure * the item is inserted at the front of the list or at the end of the * list. + * + * If there are no columns in the list-view, the item insert will + * succeed. If column 0 is then inserted late, the item information + * shows up correctly. But, ListView_SetItem() will fail for a + * subitem if there is no column for that subitem. To prevent things + * getting hopelessly out of sync, if the user tries to add a full row + * with more subitems than columns, we raise a syntax condition. + * + * On the other hand, if there is a column for the subitem, I've never + * seen ListView_SetItem() fail. We check for a failure, and if one + * is detected, we deleted the aready inserted item and return -1. */ int32_t fullRowOperation(RexxMethodContext *c, RexxObjectPtr row, FullRowOp type, void *pCSelf) { @@ -1246,12 +1257,33 @@ pcdc->lastItem = itemIndex; protectLviUserData(c, pcdc, pclvfr->subItems[0]); + uint32_t cColumns = (uint32_t)getColumnCount(pcdc->hCtrl); + if ( cColumns == (uint32_t)-1 ) + { + severeErrorException(c->threadContext, "the list-view control reports it has no columns; can not continue"); + goto done_out; + } + size_t count = pclvfr->subItemCount; + + if ( count >= cColumns ) + { + char buffer[256]; + _snprintf(buffer, sizeof(buffer), "subitem count (%d) is invalid for column count(%d)", count, cColumns); + userDefinedMsgException(c, buffer); + + goto done_out; + } + for ( size_t i = 1; i <= count; i++) { LPLVITEM subItem = pclvfr->subItems[i]; subItem->iItem = itemIndex; - ListView_SetItem(hwnd, subItem); + if ( ! ListView_SetItem(hwnd, subItem) ) + { + ListView_DeleteItem(hwnd, itemIndex); + itemIndex = -1; + } } } @@ -2331,17 +2363,23 @@ * the subitems is dependent on the coulumn count. Testing has shown * that once the column is inserted, getColumnCount() returns the * correct number, even if the list-view is not in report view. + * + * Note that if userForSorting is true, we always create a new item. */ RexxMethod3(RexxObjectPtr, lv_getFullRow, uint32_t, itemIndex, OPTIONAL_logical_t, useForSorting, CSELF, pCSelf) { - HWND hList = getDChCtrl(pCSelf); + pCLvFullRow pclvfr = NULL; + HWND hList = getDChCtrl(pCSelf); - // If we have a full row, update it and return it. - pCLvFullRow pclvfr = maybeGetFullRow(hList, itemIndex); - if ( pclvfr != NULL ) + if ( ! useForSorting ) { - updateFullRowItemState(pclvfr); - return pclvfr->rexxSelf; + // If we have a full row, update it and return it. + pclvfr = maybeGetFullRow(hList, itemIndex); + if ( pclvfr != NULL ) + { + updateFullRowItemState(pclvfr); + return pclvfr->rexxSelf; + } } // Okay, no LvFullRow object as the user data (lParam), so create a @@ -4058,88 +4096,10 @@ * An undocumented method to make it easier to do development testing * */ -RexxMethod3(RexxObjectPtr, lv_zTest, uint32_t, itemIndex, uint32_t, subItemIndex, CSELF, pCSelf) +RexxMethod1(RexxObjectPtr, lv_zTest, CSELF, pCSelf) { printf("zTest() no test at this time\n"); -#if 0 - printf("zTest() itemIndex=%d subItemIndex=%d\n", itemIndex, subItemIndex); - - pCDialogControl pcdc = validateDCCSelf(context, pCSelf); - if ( pcdc == NULL ) - { - return TheFalseObj; - } - - uint32_t count = ListView_GetItemCount(pcdc->hCtrl); - for ( uint32_t i = 0; i < count; i++ ) - { - pCLvFullRow pclvfr = maybeGetFullRow(pcdc->hCtrl, i); - printf("Item=%d subitem count=%d\n", i, pclvfr->subItemCount); - - for ( uint32_t j = 1; j <= pclvfr->subItemCount; j++ ) - { - printf(" subitem=%d\n imageIndex=%d\n cchTextMax=%d\n text=%s\n", j, pclvfr->subItems[j]->iImage, - pclvfr->subItems[j]->cchTextMax, - pclvfr->subItems[j]->pszText == LPSTR_TEXTCALLBACK ? "textCallBack" : pclvfr->subItems[j]->pszText); - } - } - - /* - LVCOLUMN lvc = { 0 }; - lvc.mask = LVCF_WIDTH | LVCF_SUBITEM; - if ( ListView_GetColumn(pcdc->hCtrl, subItemIndex, &lvc) ) - { - printf("ListView_GetColumn() returns TRUE lvc.iSubItem=%d\n", lvc.iSubItem); - } - else - { - printf("ListView_GetColumn() returns FALSE lvc.iSubItem=%d\n", lvc.iSubItem); - } - */ - - /* - LVITEM lvi = { 0 }; - lvi.iItem = itemIndex; - lvi.iSubItem = subItemIndex; - lvi.mask = LVIF_TEXT | LVIF_IMAGE; - - //char buf[1024] = { '\0' }; - char buf[1024] = "My subitem text"; - lvi.pszText = buf; - lvi.cchTextMax = 1024; - - printf("pszText=%p\n", lvi.pszText); - */ - - /* - if ( ListView_GetItem(pcdc->hCtrl, &lvi) ) - { - printf("ListView_GetItem() returns TRUE imageIndex=%d pszText=%p pszText == LPSTR_TEXTCALLBACK=%d\n", - lvi.iImage, lvi.pszText, lvi.pszText == LPSTR_TEXTCALLBACK); - if ( lvi.pszText != NULL && lvi.pszText != LPSTR_TEXTCALLBACK ) - { - printf("Got text=%s\n", lvi.pszText); - } - } - else - { - printf("ListView_GetItem() returns FALSE\n"); - } - */ - - /* - if ( ListView_SetItem(pcdc->hCtrl, &lvi) ) - { - printf("ListView_SetItem() returns TRUE\n"); - } - else - { - printf("ListView_SetItem() returns FALSE\n"); - } - */ -#endif - return TheTrueObj; } Modified: ooDialog/trunk/ooDialog/oodUtilities.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodUtilities.cpp 2012-12-06 23:58:35 UTC (rev 8662) +++ ooDialog/trunk/ooDialog/oodUtilities.cpp 2012-12-07 00:01:57 UTC (rev 8663) @@ -1379,13 +1379,18 @@ /** SPI::nonClientMetrics [class attribute get] + * + * Not implemented, perhaps for 4.2.2. */ RexxMethod0(RexxObjectPtr, spi_getNonClientMetrics_cls) { RexxMethodContext *c = context; oodResetSysErrCode(context->threadContext); - RexxDirectoryObject result = c->NewDirectory(); + context->RaiseException0(Rexx_Error_Unsupported_method); + return TheNilObj; + + RexxDirectoryObject result = context->NewDirectory(); NONCLIENTMETRICS ncm = { 0 }; ncm.cbSize = sizeof(NONCLIENTMETRICS ); @@ -1402,11 +1407,16 @@ } /** SPI::nonClientMetrics [class attribute set] + * + * Not implemented, perhaps for 4.2.2. */ RexxMethod2(RexxObjectPtr, spi_setNonClientMetrics_cls, RexxObjectPtr, data, CSELF, pCSelf) { oodResetSysErrCode(context->threadContext); + context->RaiseException0(Rexx_Error_Unsupported_method); + return NULLOBJECT; + NONCLIENTMETRICS ncm = { 0 }; ncm.cbSize = sizeof(NONCLIENTMETRICS ); |
From: <mie...@us...> - 2012-12-09 21:36:01
|
Revision: 8671 http://sourceforge.net/p/oorexx/code-0/8671 Author: miesfeld Date: 2012-12-09 21:35:57 +0000 (Sun, 09 Dec 2012) Log Message: ----------- ooDialog - add a ListView exampl showing column icons, sorting, and full rows; reorganize the examples somewhat Modified Paths: -------------- ooDialog/trunk/MakeFile ooDialog/trunk/examples/Makefile.am ooDialog/trunk/examples/controls/Makefile.am ooDialog/trunk/examples/controls/ReadMe.txt ooDialog/trunk/examples/controls/ToolTip/Makefile.am ooDialog/trunk/examples/examples/ReadMe.txt ooDialog/trunk/examples/res/res.mak ooDialog/trunk/examples/sample.rex ooDialog/trunk/install/ooDialog.nsi Added Paths: ----------- ooDialog/trunk/examples/controls/ListView/ ooDialog/trunk/examples/controls/ListView/Makefile.am ooDialog/trunk/examples/controls/ListView/ReadMe.txt ooDialog/trunk/examples/controls/ListView/columnClickListView.rex ooDialog/trunk/examples/controls/ListView/columnIcons.rex ooDialog/trunk/examples/controls/ListView/customDrawListview.rex ooDialog/trunk/examples/controls/ListView/rc/ ooDialog/trunk/examples/controls/ListView/rc/Makefile.am ooDialog/trunk/examples/controls/ListView/rc/columnIcons.h ooDialog/trunk/examples/controls/ListView/rc/columnIcons.rc ooDialog/trunk/examples/controls/ListView/rc/columnIcons_16.bmp ooDialog/trunk/examples/controls/ListView/rc/columnIcons_32.bmp ooDialog/trunk/examples/controls/ListView/rc/customDrawListView.h ooDialog/trunk/examples/controls/ListView/rc/customDrawListView.rc ooDialog/trunk/examples/controls/ListView/rc/res.mak ooDialog/trunk/examples/controls/ToolTip/ReadMe.txt ooDialog/trunk/examples/controls/TreeView/ ooDialog/trunk/examples/controls/TreeView/Makefile.am ooDialog/trunk/examples/controls/TreeView/rc/ ooDialog/trunk/examples/controls/TreeView/rc/Makefile.am ooDialog/trunk/examples/controls/TreeView/rc/treeViewCustomDraw.bmp ooDialog/trunk/examples/controls/TreeView/rc/treeViewCustomDraw.h ooDialog/trunk/examples/controls/TreeView/rc/treeViewCustomDraw.rc ooDialog/trunk/examples/controls/TreeView/treeViewCustomDraw.inp ooDialog/trunk/examples/controls/TreeView/treeViewCustomDraw.rex ooDialog/trunk/examples/controls/TreeView/treeViewCustomDrawI.inp ooDialog/trunk/examples/propertySheet.tabControls/ Removed Paths: ------------- ooDialog/trunk/examples/bmp/treeViewCustomDraw.bmp ooDialog/trunk/examples/controls/customDrawListView.h ooDialog/trunk/examples/controls/customDrawListView.rc ooDialog/trunk/examples/controls/customDrawListview.rex ooDialog/trunk/examples/examples/columnClickListView.rex ooDialog/trunk/examples/propertySheet.tabs/ ooDialog/trunk/examples/rc/treeViewCustomDraw.h ooDialog/trunk/examples/rc/treeViewCustomDraw.rc ooDialog/trunk/examples/treeViewCustomDraw.inp ooDialog/trunk/examples/treeViewCustomDraw.rex ooDialog/trunk/examples/treeViewCustomDrawI.inp Modified: ooDialog/trunk/MakeFile =================================================================== --- ooDialog/trunk/MakeFile 2012-12-09 05:25:07 UTC (rev 8670) +++ ooDialog/trunk/MakeFile 2012-12-09 21:35:57 UTC (rev 8671) @@ -165,6 +165,8 @@ @cd $(OOD_ROOT_DIR)\examples\res @set MACHINE=$(CPU) $(MAKE) /NOLOGO /F res.mak + @cd $(OOD_ROOT_DIR)\examples\controls\ListView\rc + $(MAKE) /NOLOGO /F res.mak @cd $(OOD_ROOT_DIR)\examples\userGuide\exercises\Samples\DlgData\res $(MAKE) /NOLOGO /F res.mak @cd $(OOD_ROOT_DIR)\examples\userGuide\exercises\Exercise05\res Modified: ooDialog/trunk/examples/Makefile.am =================================================================== --- ooDialog/trunk/examples/Makefile.am 2012-12-09 05:25:07 UTC (rev 8670) +++ ooDialog/trunk/examples/Makefile.am 2012-12-09 21:35:57 UTC (rev 8671) @@ -37,10 +37,10 @@ .NOTPARALLEL: -SUBDIRS = bmp controls examples menus mouse oleinfo ooRexxTry propertySheet.tabs rc res simple sysinfo tutorial userGuide wav winsystem -DIST_SUBDIRS = bmp controls examples menus mouse oleinfo ooRexxTry propertySheet.tabs rc res simple sysinfo tutorial userGuide wav winsystem +SUBDIRS = bmp controls examples menus mouse oleinfo ooRexxTry propertySheet.tabControls rc res simple sysinfo tutorial userGuide wav winsystem +DIST_SUBDIRS = bmp controls examples menus mouse oleinfo ooRexxTry propertySheet.tabControls rc res simple sysinfo tutorial userGuide wav winsystem MAINTAINERCLEANFILES = Makefile.in *~ -EXTRA_DIST = *.rex *.h *.inp *.ico +EXTRA_DIST = *.rex *.h *.ico Deleted: ooDialog/trunk/examples/bmp/treeViewCustomDraw.bmp =================================================================== (Binary files differ) Added: ooDialog/trunk/examples/controls/ListView/Makefile.am =================================================================== --- ooDialog/trunk/examples/controls/ListView/Makefile.am (rev 0) +++ ooDialog/trunk/examples/controls/ListView/Makefile.am 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,46 @@ +#/*----------------------------------------------------------------------------*/ +#/* */ +#/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +#/* */ +#/* This program and the accompanying materials are made available under */ +#/* the terms of the Common Public License v1.0 which accompanies this */ +#/* distribution. A copy is also available at the following address: */ +#/* http://www.oorexx.org/license.html */ +#/* */ +#/* Redistribution and use in source and binary forms, with or */ +#/* without modification, are permitted provided that the following */ +#/* conditions are met: */ +#/* */ +#/* Redistributions of source code must retain the above copyright */ +#/* notice, this list of conditions and the following disclaimer. */ +#/* Redistributions in binary form must reproduce the above copyright */ +#/* notice, this list of conditions and the following disclaimer in */ +#/* the documentation and/or other materials provided with the distribution. */ +#/* */ +#/* Neither the name of Rexx Language Association nor the names */ +#/* of its contributors may be used to endorse or promote products */ +#/* derived from this software without specific prior written permission. */ +#/* */ +#/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +#/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +#/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +#/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +#/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +#/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +#/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +#/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +#/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +#/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +#/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#/* */ +#/*----------------------------------------------------------------------------*/ + +.NOTPARALLEL: + +SUBDIRS = rc +DIST_SUBDIRS = rc + +MAINTAINERCLEANFILES = Makefile.in *~ + +EXTRA_DIST = *.rex + Property changes on: ooDialog/trunk/examples/controls/ListView/Makefile.am ___________________________________________________________________ Added: svn:eol-style + native Added: ooDialog/trunk/examples/controls/ListView/ReadMe.txt =================================================================== --- ooDialog/trunk/examples/controls/ListView/ReadMe.txt (rev 0) +++ ooDialog/trunk/examples/controls/ListView/ReadMe.txt 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,65 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2009-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + + ReadMe + + 1. ooDialog - Dialog Control Example Programs + ----------------------------------------------- + + This directory contains example programs that demonstrate how to use the + list-view control in ooDialog. The examples range from simple to medium + complex. + + - columnClickListView.rex + + An example program that shows how to determine which row and which + column in a list view control the user has clicked on. + + - customDrawListView.rex + + Shows how to use a list-view with emphasis on custom draw. Custom + draw with a list-view allows you set the text color, background color, + and font for individuals list-view items. And when the list-view is + in report view, this can be done for individual subitems of each row. + + - columnIcons.rex + + This example shows how to use icons for all columns in a list-view, + how to use LvFullRow objects to populate a list-view, and how to use + the internal sorting feature of the ooDialog framework. In report + view, the columns can be drag and droppred to arrange the order. + Clicking on a column sorts the column. Property changes on: ooDialog/trunk/examples/controls/ListView/ReadMe.txt ___________________________________________________________________ Added: svn:eol-style + native Copied: ooDialog/trunk/examples/controls/ListView/columnClickListView.rex (from rev 8663, ooDialog/trunk/examples/examples/columnClickListView.rex) =================================================================== --- ooDialog/trunk/examples/controls/ListView/columnClickListView.rex (rev 0) +++ ooDialog/trunk/examples/controls/ListView/columnClickListView.rex 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,97 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2010-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * A simple List View control using ooDialog. Demonstrates how to determine + * which column within a row the user has clicked on. + * + * Note that you must add the FULLROWSELECT extended style to the list view in + * order to get the correct row number. If the list view does not have this + * style, Windows only reports the row number if the text label in the left- + * most column is clicked on. + * + * Each time the user clicks on the list view control, the row and column + * clicked are reported. This is done using "say" so the program is best + * run from a command prompt window. + */ + + dlg = .SimpleLV~new + if dlg~initCode = 0 then do + -- Add a symbolic resource ID for the list view. + dlg~constDir[IDC_LISTVIEW] = 200 + + dlg~create(30, 30, 325, 200, "A Simple List View", "VISIBLE") + dlg~execute("SHOWTOP") + end + +-- End of entry point. + +::requires "ooDialog.cls" + +::class 'SimpleLV' subclass UserDialog + +::method defineDialog + + self~createListView(IDC_LISTVIEW, 10, 20, 305, 145, "REPORT SHOWSELALWAYS") + self~createPushButton(IDOK, 280, 175, 35, 15, "DEFAULT", "Close") + + self~connectListViewEvent(IDC_LISTVIEW, "CLICK", onClick) + +::method initDialog + + -- Get a reference to the list view. + list = self~newListView(IDC_LISTVIEW) + + list~addExtendedStyle("FULLROWSELECT GRIDLINES CHECKBOXES HEADERDRAGDROP") + + list~insertColumn(0, "Row (Column 1)", 75) + list~insertColumn(1, "Column 2", 70) + list~insertColumn(2, "Column 3", 70) + + do i = 1 to 200 + list~addRow(i, , "Line" i, "Line / Col ("i", 2)", "Line / Col ("i", 3)") + end + +::method onClick + use arg id, itemIndex, columnIndex, keyState + + -- Compensate for zero-based indexes ;-( + itemIndex += 1 + columnIndex += 1 + + say 'onClick() row:' itemIndex 'column:' columnIndex 'key state:' keyState + Added: ooDialog/trunk/examples/controls/ListView/columnIcons.rex =================================================================== --- ooDialog/trunk/examples/controls/ListView/columnIcons.rex (rev 0) +++ ooDialog/trunk/examples/controls/ListView/columnIcons.rex 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,220 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * This example shows ... + * + * + */ + + .application~useGlobalConstDir('O', "rc\columnIcons.h") + + dlg = .ListViews~new("rc\columnIcons.dll", IDD_DIALOG) + if dlg~initCode == 0 then do + dlg~execute("SHOWTOP", IDI_DLG_OOREXX) + end + else do + say 'Dialog failed to initialize, aborting.' + return 99 + end + + return 0 +-- End of entry point. + +::requires "ooDialog.cls" + +::class 'ListViews' subclass ResDialog + +::method initDialog + expose list itemColumns + + list = self~newListView(IDC_LV_VIEWS) + self~newRadioButton(IDC_RB_ICON)~check + + itemColumns = .array~of(-1, -1, -1, -1) + + self~connectEvents + self~setImageLists + self~populateList(list) + + +::method onReport + expose list + list~setView("REPORT") + +::method onList + expose list + list~setView("LIST") + +::method onIcon + expose list + list~setView("ICON") + +::method onSmallIcon + expose list + list~setView("SMALLICON") + +::method onColClick unguarded + expose list itemColumns + use arg id, colIndex + + -- Adjust for 0-based indexes + i = colIndex + 1 + + d = .directory~new + d~column = colIndex + d~caseless = .false + + if itemColumns[i] == -1 then do + d~ascending = .true + itemColumns[i] = 0 + end + else if itemColumns[i] == 0 then do + d~ascending = .false + itemColumns[i] = 1 + end + else do + d~ascending = .true + itemColumns[i] = 0 + end + + list~sortItems('InternalListViewSort', d) + return 0 + + +::method connectEvents private + + self~connectButtonEvent(IDC_RB_REPORT, "CLICKED", onReport) + self~connectButtonEvent(IDC_RB_LIST, "CLICKED", onList) + self~connectButtonEvent(IDC_RB_ICON, "CLICKED", onIcon) + self~connectButtonEvent(IDC_RB_SMALL_ICON, "CLICKED", onSmallIcon) + self~connectListViewEvent(IDC_LV_VIEWS, "COLUMNCLICK", onColClick, .true) + + +::method setImageLists private + expose list + + resourceImage = .ResourceImage~new('ignored', self) + smIcons = resourceImage~getImage(IDB_SMALL_ICONS) + normalIcons = resourceImage~getImage(IDB_NORMAL_ICONS) + + flags = .Image~toId(ILC_COLOR24) + imageList = .ImageList~create(.Size~new(16), flags, 28, 0) + imageList~add(smIcons) + + list~setImageList(imageList, .Image~toId(LVSIL_SMALL)) + + imageList = .ImageList~create(.Size~new(32), flags, 9, 0) + imageList~add(normalIcons) + + list~setImageList(imageList, .Image~toId(LVSIL_NORMAL)) + + +::method populateList private + use strict arg list + + list~InsertColumnPx(0, "Title", 150) + list~InsertColumnPx(1, "Name", 75) + list~InsertColumnPx(2, "Last", 100) + list~InsertColumnPx(3, "e-mail", 150) + + style = "FULLROWSELECT UNDERLINEHOT ONECLICKACTIVATE SUBITEMIMAGES HEADERDRAGDROP" + list~addExtendedStyle(style) + + lvItem = .LvItem~new(0, "Business manager", 6) + lvSub1 = .LvSubItem~new(0, 1, "Tom", 14) + lvSub2 = .LvSubItem~new(0, 2, "Sawyer", 26) + lvSub3 = .LvSubItem~new(0, 3, "ts...@go...", 11) + lvFullRow = .LvFullRow~new(lvItem, lvSub1, lvSub2, lvSub3, .true) + list~addFullRow(lvFullRow) + + lvItem = .LvItem~new(1, "Software Developer", 1) + lvSub1 = .LvSubItem~new(1, 1, "Sam", 14) + lvSub2 = .LvSubItem~new(1, 2, "Frank", 15) + lvSub3 = .LvSubItem~new(1, 3, "bo...@gm...", 12) + lvFullRow = .LvFullRow~new(lvItem, lvSub1, lvSub2, lvSub3, .true) + list~addFullRow(lvFullRow) + + lvItem = .LvItem~new(2, "Mechanical Engineer", 0) + lvSub1 = .LvSubItem~new(2, 1, "Tamara", 13) + lvSub2 = .LvSubItem~new(2, 2, "Ecclestone", 16) + lvSub3 = .LvSubItem~new(2, 3, "tam...@ya...", 9) + lvFullRow = .LvFullRow~new(lvItem, lvSub1, lvSub2, lvSub3, .true) + list~addFullRow(lvFullRow) + + lvItem = .LvItem~new(3, "Lawyer", 5) + lvSub1 = .LvSubItem~new(3, 1, "Mary", 13) + lvSub2 = .LvSubItem~new(3, 2, "Tyler", 17) + lvSub3 = .LvSubItem~new(3, 3, "fk...@qu...", 10) + lvFullRow = .LvFullRow~new(lvItem, lvSub1, lvSub2, lvSub3, .true) + list~addFullRow(lvFullRow) + + lvItem = .LvItem~new(4, "Doctor", 2) + lvSub1 = .LvSubItem~new(4, 1, "Cienna", 13) + lvSub2 = .LvSubItem~new(4, 2, "Acer", 18) + lvSub3 = .LvSubItem~new(4, 3, "ca...@sh...", 11) + lvFullRow = .LvFullRow~new(lvItem, lvSub1, lvSub2, lvSub3, .true) + list~addFullRow(lvFullRow) + + lvItem = .LvItem~new(5, "Clerk", 3) + lvSub1 = .LvSubItem~new(5, 1, "Harry", 14) + lvSub2 = .LvSubItem~new(5, 2, "Houdini", 19) + lvSub3 = .LvSubItem~new(5, 3, "HH...@ma...", 12) + lvFullRow = .LvFullRow~new(lvItem, lvSub1, lvSub2, lvSub3, .true) + list~addFullRow(lvFullRow) + + lvItem = .LvItem~new(6, "Nurse", 4) + lvSub1 = .LvSubItem~new(6, 1, "Mike", 14) + lvSub2 = .LvSubItem~new(6, 2, "Thompson", 18) + lvSub3 = .LvSubItem~new(6, 3, "mi...@mi...", 10) + lvFullRow = .LvFullRow~new(lvItem, lvSub1, lvSub2, lvSub3, .true) + list~addFullRow(lvFullRow) + + lvItem = .LvItem~new(7, "Drywall Finisher", 7) + lvSub1 = .LvSubItem~new(7, 1, "Larry", 14) + lvSub2 = .LvSubItem~new(7, 2, "Goodell", 20) + lvSub3 = .LvSubItem~new(7, 3, "wa...@ya...", 9) + lvFullRow = .LvFullRow~new(lvItem, lvSub1, lvSub2, lvSub3, .true) + list~addFullRow(lvFullRow) + + lvItem = .LvItem~new(8, "Biochemist", 8) + lvSub1 = .LvSubItem~new(8, 1, "Kumar", 14) + lvSub2 = .LvSubItem~new(8, 2, "Patel", 18) + lvSub3 = .LvSubItem~new(8, 3, "kp...@se...", 10) + lvFullRow = .LvFullRow~new(lvItem, lvSub1, lvSub2, lvSub3, .true) + list~addFullRow(lvFullRow) + Property changes on: ooDialog/trunk/examples/controls/ListView/columnIcons.rex ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Copied: ooDialog/trunk/examples/controls/ListView/customDrawListview.rex (from rev 8663, ooDialog/trunk/examples/controls/customDrawListview.rex) =================================================================== --- ooDialog/trunk/examples/controls/ListView/customDrawListview.rex (rev 0) +++ ooDialog/trunk/examples/controls/ListView/customDrawListview.rex 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,264 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * This example shows how to work with a simple ListView control in report + * view. + * + * The main points of the example are: + * + * 1.) It shows how to use the LvFullRow, LvItem, and LvSubItem objects to add + * items to list-views + * + * 2.) It shows how to use custom draw with a list-view change the text and + * background color of a single list-view item, and / or change the font + * for a single item. + * + * Note that in the .rc file, the resource script file, for this example, the + * dialog is created *not* visible. Thus, while the dialog is being + * initialized, it is not visible on the screen. This eliminates flicker while + * the items are being inserted into the list-view. Some people like the users + * of their applications to see the list-view being filled, some people dislike + * flicker. So, it is mostly a matter of preference how you create the dialog, + * initially visible, or initially invisible. But, it is good to be aware of + * the option. + */ + + -- Set the defaults for this application. Use the global .constDir 'O'nly, + -- Read the 'customDrawListview.h' file for symbolic resource ID + -- definitions. And, turn automatica data detection off (.false.) + .application~setDefaults('O', 'rc\customDrawListview.h', .false) + + dlg = .CustomDrawDlg~new('rc\customDrawListview.rc', IDD_CUSTOMDRAW) + if dlg~initCode = 0 then do + dlg~execute("SHOWTOP") + end + +return 0 +-- End of entry point. + +::requires "ooDialog.cls" + +/** CustomDrawDlg + * + * Our dialog subclass. To use custom draw, you need to inherit the CustomDraw + * mixin class. + */ +::class 'CustomDrawDlg' subclass RcDialog inherit CustomDraw + +/** init() + * + * To recieve the custom draw event notifications, you need to: 1.) Init the + * custom draw interface, 2.) name the control you want the custom draw + * notifications for. + * + * 1.) You must init the custom draw interface before invoking any of the custom + * draw methods. This is done by invoking the customDraw() method. + * + * 2.) You name the control you want the custom draw notifications for by + * invoking the forControl() method with: the resource ID of the control, the + * string name of the control, and the name of the method to be invoked. + * + * At this time, only ListView controls are supported. Future versions of + * ooDialog may support more dialog controls. + * + * Note that we created the colors and font one time here, rather than create + * them each time the onCustomDraw() method is invoked. + * + * We also create our LvFullRows objects here rather than in initDialog(). This + * helps allow the dialog to open with everything appearing at once. The full + * rows are inserted into the list-view in initDialog(). The rows can only be + * inserted after the underlying Windows dialog exists. + */ +::method init + expose textRed textBlack textBlue rowGreen rowLiteBlue rowYellow rows checkedFont + + forward class (super) continue + + self~customDraw + self~customDrawControl(IDC_LV_CUSTOM, 'ListView', onCustomDraw) + + textBlack = self~RGB( 0, 0, 0) + textRed = self~RGB(247, 7, 59) + textBlue = self~RGB( 17, 5, 250) + rowYellow = self~RGB(245, 245, 127) + rowLiteBlue = self~RGB(115, 245, 186) + rowGreen = self~RGB(188, 237, 102) + + checkedFont = self~createFontEx("Courier New", 10) + + rows = self~createRows + +/** initDialog() + * + * initDialog is the place to do any initialization that requires the underlying + * dialog to exist. Here we add some extended list-view styles and fill the + * list-view with its items. + */ +::method initDialog + expose list rows + + list = self~newListView(IDC_LV_CUSTOM) + + list~addExtendedStyle("FULLROWSELECT GRIDLINES CHECKBOXES HEADERDRAGDROP") + + list~InsertColumn(0, "Line text", 75) + list~InsertColumn(1, "Line number", 55) + list~InsertColumn(2, "Numbers", 50) + list~InsertColumn(3, "Characters", 55) + + list~prepare4nItems(rows~items) + do r over rows + list~addFullRow(r) + end + + +/** onCustomDraw() + * + * This is the event handler that is invoked whenever the list-view needs to + * draw any item in the list. + * + * We are passed a LvCustomDrawSimple object to us. This object's attributes + * contain information concerning which item the list-view needs to draw, and + * other information related to doing custom drawing. Other attributes of the + * object need to be set by us in order to control the drawing. + * + * You must return true or false from this event handler. Failure to do so will + * terminate the dialog and raise a condition. Returning false basically says + * you do not want to do any custom drawing for this item. + * + * You can change the text color, the background color, and the font by setting + * those attributes of the LvCustomDrawSimple object. You also need to set the + * reply attribute. This attribute is the reply sent back to the list-view. + * + * For this example, we return CDRF_NEWFONT to tell the list-view that either + * colors, or fonts, were changed and that we do not want to recieve subitem + * notifications. Other possible replies are not discussed here as they are not + * pertinent to this example. The ooDialog documentation describes the other + * possible replies. + * + * The logic of what we are doing is relatively simple. We color every other + * row with a different color, if the user has not checked the row. All checked + * rows use a differnt color and font than the unchecked rows. + */ +::method onCustomDraw unguarded + expose list textRed textBlack textBlue rowGreen rowLiteBlue rowYellow checkedFont + use arg lvcds + + item = lvcds~item + + if (item // 2) == 0 then do + if list~isChecked(item) then do + lvcds~clrText = textBlue + lvcds~clrTextBk = rowLiteBlue + lvcds~font = checkedFont + end + else do + lvcds~clrText = textRed + lvcds~clrTextBk = rowYellow + end + end + else do + if list~isChecked(item) then do + lvcds~clrText = textBlue + lvcds~clrTextBk = rowLiteBlue + lvcds~font = checkedFont + end + else do + lvcds~clrText = textBlack + lvcds~clrTextBk = rowGreen + end + end + + lvcds~reply = self~CDRF_NEWFONT + return .true + + +/** createRows() + * + * Here we create LvFullRow objects for every list-view item. LvItem objects + * represent the list-view item and LvSubItem objects represent each column in + * the list-view item. + * + * All the full row objects are put into an array. The array is later used to + * insert all the items into the list-view. + */ +::method createRows private + + rows = .array~new(10) + + do i = 1 to 1000 + j = i - 1 + lvi = .LvItem~new(j, 'Line' i, , p) + lvsi1 = .LvSubItem~new(j, 1, i) + lvsi2 = .LvSubItem~new(j, 2, random(1, 200)) + lvsi3 = .LvSubItem~new(j, 3, self~randomChars) + + rows[i] = .LvFullRow~new(lvi, lvsi1, lvsi2, lvsi3, .false) + end + + return rows + + +/** randomChars() + * + * Simple method to generate some random string of characters. + */ +::method randomChars private + + len = random(1, 7) + chars = '' + + do i = 1 to len + chars || = random(97, 122)~d2c + end + + return chars + + +/** leaving() + * + * This method is invoked automatically be the ooDialog framework when the + * dialog is closed. It should be used to do any needed clean up. Here we + * delete the font we created. + * + * Note that the colors we created are just numbers and do not represent any + * system resource. + */ +::method leaving unguarded + expose checkedFont + self~deleteFont(checkedFont) Added: ooDialog/trunk/examples/controls/ListView/rc/Makefile.am =================================================================== --- ooDialog/trunk/examples/controls/ListView/rc/Makefile.am (rev 0) +++ ooDialog/trunk/examples/controls/ListView/rc/Makefile.am 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,43 @@ +#/*----------------------------------------------------------------------------*/ +#/* */ +#/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +#/* */ +#/* This program and the accompanying materials are made available under */ +#/* the terms of the Common Public License v1.0 which accompanies this */ +#/* distribution. A copy is also available at the following address: */ +#/* http://www.oorexx.org/license.html */ +#/* */ +#/* Redistribution and use in source and binary forms, with or */ +#/* without modification, are permitted provided that the following */ +#/* conditions are met: */ +#/* */ +#/* Redistributions of source code must retain the above copyright */ +#/* notice, this list of conditions and the following disclaimer. */ +#/* Redistributions in binary form must reproduce the above copyright */ +#/* notice, this list of conditions and the following disclaimer in */ +#/* the documentation and/or other materials provided with the distribution. */ +#/* */ +#/* Neither the name of Rexx Language Association nor the names */ +#/* of its contributors may be used to endorse or promote products */ +#/* derived from this software without specific prior written permission. */ +#/* */ +#/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +#/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +#/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +#/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +#/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +#/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +#/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +#/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +#/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +#/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +#/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#/* */ +#/*----------------------------------------------------------------------------*/ + +.NOTPARALLEL: + +MAINTAINERCLEANFILES = Makefile.in *~ + +EXTRA_DIST = *.bmp *.h *.rc + Property changes on: ooDialog/trunk/examples/controls/ListView/rc/Makefile.am ___________________________________________________________________ Added: svn:eol-style + native Added: ooDialog/trunk/examples/controls/ListView/rc/columnIcons.h =================================================================== --- ooDialog/trunk/examples/controls/ListView/rc/columnIcons.h (rev 0) +++ ooDialog/trunk/examples/controls/ListView/rc/columnIcons.h 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,50 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +#ifndef IDC_STATIC +#define IDC_STATIC (-1) +#endif + +#define IDD_DIALOG 100 +#define IDB_NORMAL_ICONS 104 +#define IDB_SMALL_ICONS 105 +#define IDC_ST_VIEW 1003 +#define IDC_RB_REPORT 1005 +#define IDC_RB_LIST 1007 +#define IDC_RB_ICON 1009 +#define IDC_RB_SMALL_ICON 1011 +#define IDC_LV_VIEWS 1012 Property changes on: ooDialog/trunk/examples/controls/ListView/rc/columnIcons.h ___________________________________________________________________ Added: svn:eol-style + native Added: ooDialog/trunk/examples/controls/ListView/rc/columnIcons.rc =================================================================== --- ooDialog/trunk/examples/controls/ListView/rc/columnIcons.rc (rev 0) +++ ooDialog/trunk/examples/controls/ListView/rc/columnIcons.rc 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,65 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +#include <windows.h> +#include <winuser.h> +#include <commctrl.h> +#include "columnIcons.h" + + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +IDB_SMALL_ICONS BITMAP ".\\columnIcons_16.bmp" + + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +IDB_NORMAL_ICONS BITMAP ".\\columnIcons_32.bmp" + + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +IDD_DIALOG DIALOGEX 0, 0, 342, 249 +STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU +CAPTION "Views of the List-view Control" +FONT 8, "Ms Shell Dlg 2", 400, 0, 1 +{ + CONTROL "", IDC_LV_VIEWS, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_ICON, 10, 10, 322, 171 + GROUPBOX "View", IDC_ST_VIEW, 10, 186, 153, 53, WS_GROUP + AUTORADIOBUTTON "Report View", IDC_RB_REPORT, 21, 201, 55, 10, WS_TABSTOP + AUTORADIOBUTTON "List View", IDC_RB_LIST, 21, 221, 55, 10 + AUTORADIOBUTTON "Icon View", IDC_RB_ICON, 96, 201, 55, 10 + AUTORADIOBUTTON "Small Icon View", IDC_RB_SMALL_ICON, 96, 221, 65, 10 + DEFPUSHBUTTON "OK", IDOK, 282, 225, 50, 14, WS_GROUP +} Property changes on: ooDialog/trunk/examples/controls/ListView/rc/columnIcons.rc ___________________________________________________________________ Added: svn:eol-style + native Added: ooDialog/trunk/examples/controls/ListView/rc/columnIcons_16.bmp =================================================================== (Binary files differ) Property changes on: ooDialog/trunk/examples/controls/ListView/rc/columnIcons_16.bmp ___________________________________________________________________ Added: svn:mime-type + image/bmp Added: ooDialog/trunk/examples/controls/ListView/rc/columnIcons_32.bmp =================================================================== (Binary files differ) Property changes on: ooDialog/trunk/examples/controls/ListView/rc/columnIcons_32.bmp ___________________________________________________________________ Added: svn:mime-type + image/bmp Copied: ooDialog/trunk/examples/controls/ListView/rc/customDrawListView.h (from rev 8663, ooDialog/trunk/examples/controls/customDrawListView.h) =================================================================== --- ooDialog/trunk/examples/controls/ListView/rc/customDrawListView.h (rev 0) +++ ooDialog/trunk/examples/controls/ListView/rc/customDrawListView.h 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,43 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +#ifndef IDC_STATIC +#define IDC_STATIC (-1) +#endif + +#define IDD_CUSTOMDRAW 101 +#define IDC_LV_CUSTOM 1002 Copied: ooDialog/trunk/examples/controls/ListView/rc/customDrawListView.rc (from rev 8663, ooDialog/trunk/examples/controls/customDrawListView.rc) =================================================================== --- ooDialog/trunk/examples/controls/ListView/rc/customDrawListView.rc (rev 0) +++ ooDialog/trunk/examples/controls/ListView/rc/customDrawListView.rc 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,52 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +#include <windows.h> +#include <winuser.h> +#include <commctrl.h> +#include "customDraw.h" + + +LANGUAGE 0, SUBLANG_NEUTRAL +IDD_CUSTOMDRAW DIALOGEX 0, 0, 350, 200 +STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU +CAPTION "Custom Draw List View" +FONT 8, "Ms Shell Dlg", 400, 0, 1 +{ + CONTROL "", IDC_LV_CUSTOM, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT, 10, 10, 328, 153 + DEFPUSHBUTTON "OK", IDOK, 290, 176, 50, 14 +} Added: ooDialog/trunk/examples/controls/ListView/rc/res.mak =================================================================== --- ooDialog/trunk/examples/controls/ListView/rc/res.mak (rev 0) +++ ooDialog/trunk/examples/controls/ListView/rc/res.mak 2012-12-09 21:35:57 UTC (rev 8671) @@ -0,0 +1,50 @@ +#/*----------------------------------------------------------------------------*/ +#/* */ +#/* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */ +#/* */ +#/* This program and the accompanying materials are made available under */ +#/* the terms of the Common Public License v1.0 which accompanies this */ +#/* distribution. A copy is also available at the following address: */ +#/* http://www.oorexx.org/license.html */ +#/* */ +#/* Redistribution and use in source and binary forms, with or */ +#/* without modification, are permitted provided that the following */ +#/* conditions are met: */ +#/* */ +#/* Redistributions of source code must retain the above copyright */ +#/* notice, this list of conditions and the following disclaimer. */ +#/* Redistributions in binary form must reproduce the above copyright ... [truncated message content] |
From: <mie...@us...> - 2012-12-13 00:15:46
|
Revision: 8687 http://sourceforge.net/p/oorexx/code-0/8687 Author: miesfeld Date: 2012-12-13 00:15:42 +0000 (Thu, 13 Dec 2012) Log Message: ----------- ooDialog, final tweaks for 4.2.1 release Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/ooDialog/oodListView.cpp Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-13 00:13:28 UTC (rev 8686) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-13 00:15:42 UTC (rev 8687) @@ -105,6 +105,8 @@ * #420 Would like to have an AddButtonStem method. +* #478 ooDialog - List-view could use a way to work with a complete row + * #483 ooDialog setColor and dialog background improvements * #484 ooDialog setColor methods should not be restricted to the 19 @@ -181,14 +183,6 @@ facility for ListView controls. -New ListView methods: ---------------------- - -addFullRow() -insertFullRow() -prependFullRow() - - New dialog classes: ------------------- @@ -222,6 +216,12 @@ useVersion() usingVersion() +In the ListView class: + +addFullRow() +insertFullRow() +prependFullRow() + In the TreeView class: find() @@ -316,8 +316,8 @@ draw for the tree-view control, and has a number of small bugs fixed. -Documentation -------------- +Documentation: +-------------- The ListView Control chapter in the ooDialog Reference Manual has been partially reviewed and corrected for accuracy. Parts of the chapter Modified: ooDialog/trunk/ooDialog/oodListView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-13 00:13:28 UTC (rev 8686) +++ ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-13 00:15:42 UTC (rev 8687) @@ -591,6 +591,15 @@ * @param pclvfr * * @assumes updateFullRowIndexes() has already been invoked. + * + * @remarks I wonder if we should set the state mask value used for the + * ListView_GetItem to the pLvi struct, and maybe |= the LVIF_STATE + * flag to the pLvi mask field in the struct? + * + * If the Rexx user examines the LvItem object after a call to + * ListView::getFullRow(), he could see maybe SELECTED FOCUSED for the + * state, but no corrsponding values in the mask and stateMask fields + * that would indicate the state attribute is valid. */ static void updateFullRowItemState(pCLvFullRow pclvfr) { @@ -4993,27 +5002,41 @@ /** LvItem::overlayImageIndex [attribute] */ -RexxMethod1(int32_t, lvi_overlayImageIndex, CSELF, pLVI) +RexxMethod1(uint32_t, lvi_overlayImageIndex, CSELF, pLVI) { return (LVIS_OVERLAYMASK & ((LPLVITEM)pLVI)->state) >> 8; } -RexxMethod2(RexxObjectPtr, lvi_setOverlayImageIndex, int32_t, index, CSELF, pLVI) +RexxMethod2(RexxObjectPtr, lvi_setOverlayImageIndex, uint16_t, index, CSELF, pLVI) { - ((LPLVITEM)pLVI)->state |= INDEXTOOVERLAYMASK(index); - ((LPLVITEM)pLVI)->stateMask |= LVIS_OVERLAYMASK; + if ( index > 15 ) + { + wrongRangeException(context, 1, 0, 15, index); + } + else + { + ((LPLVITEM)pLVI)->state |= INDEXTOOVERLAYMASK(index); + ((LPLVITEM)pLVI)->stateMask |= LVIS_OVERLAYMASK; + } return NULLOBJECT; } /** LvItem::stateImageIndex [attribute] */ -RexxMethod1(int32_t, lvi_stateImageIndex, CSELF, pLVI) +RexxMethod1(uint16_t, lvi_stateImageIndex, CSELF, pLVI) { return (LVIS_STATEIMAGEMASK & ((LPLVITEM)pLVI)->state) >> 12; } -RexxMethod2(RexxObjectPtr, lvi_setStateImageIndex, int32_t, index, CSELF, pLVI) +RexxMethod2(RexxObjectPtr, lvi_setStateImageIndex, uint16_t, index, CSELF, pLVI) { - ((LPLVITEM)pLVI)->state |= INDEXTOSTATEIMAGEMASK(index); - ((LPLVITEM)pLVI)->stateMask |= LVIS_STATEIMAGEMASK; + if ( index > 15 ) + { + wrongRangeException(context, 1, 0, 15, index); + } + else + { + ((LPLVITEM)pLVI)->state |= INDEXTOSTATEIMAGEMASK(index); + ((LPLVITEM)pLVI)->stateMask |= LVIS_STATEIMAGEMASK; + } return NULLOBJECT; } @@ -5040,7 +5063,14 @@ { uint32_t val = 0; + if ( StrCmpI(flags, "ALL") == 0 ) + { + val = LVIF_IMAGE | LVIF_NORECOMPUTE | LVIF_TEXT; + return val; + } + if ( StrStrI(flags, "IMAGE") != NULL ) val |= LVIF_IMAGE; + if ( StrStrI(flags, "NORECOMPUTE") != NULL ) val |= LVIF_NORECOMPUTE; if ( StrStrI(flags, "TEXT") != NULL ) val |= LVIF_TEXT; return val; @@ -5629,7 +5659,7 @@ * * @param subitem The subitem to add. * - * @return Returns the index of the added item, or 0 on error. + * @return Returns the index of the added subitem, or 0 on error. */ RexxMethod2(uint32_t, lvfr_addSubitem, RexxObjectPtr, subitem, CSELF, pCSelf) { |
From: <mie...@us...> - 2012-12-13 04:00:21
|
Revision: 8695 http://sourceforge.net/p/oorexx/code-0/8695 Author: miesfeld Date: 2012-12-13 04:00:18 +0000 (Thu, 13 Dec 2012) Log Message: ----------- Bump up version of ooDialog trunk to 4.2.2 and fix type in NSIS install script Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/install/ooDialog.nsi ooDialog/trunk/ooDialog/ooDialog.ver Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-13 03:41:51 UTC (rev 8694) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-13 04:00:18 UTC (rev 8695) @@ -1,40 +1,21 @@ - Release Notes ooDialog 4.2.1 (preview) - ====================================== + Release Notes ooDialog 4.2.2 + ============================ -NOTE: ------------------------------------------------------------------------- -The ooDialog 4.2.1 preview version is a SNAPSHOT of the current -development in ooDialog. It is not a beta release, or even an alpha -release. The build is placed here to allow to interested parties to try -and / or use some of the new features coming up in ooDialog 4.2.1. -Devlopment work is still on-going and new interfaces are not guarenteed. -Method names and or method arguments of features currently in -development may change before a final release. +The ooDialog 4.2.2 release ... -Please feel free to open bugs on SourceForge for bugs found in this -preview and / or discuss changes or improvements to the new features on -the ooRexx User's list. ------------------------------------------------------------------------- -ENDNOTE: - -The ooDialog 4.2.1 release is focused on improvements to the ListView -and TreeView classes in ooDialog. In addition to bug fixes, this -release contains a number of enhancements to both the list-view and -tree-view implementations in ooDialog. - -ooDialog 4.2.1 can be installed to any ooRexx installation, 4.1.0 or +ooDialog 4.2.2 can be installed to any ooRexx installation, 4.1.0 or later. Beginning with the release of ooDialog 4.2.0, the installation of -ooDialog has been decoupled from the interpreter. ooDialog 4.2.1 +ooDialog has been decoupled from the interpreter. ooDialog 4.2.2 installs over the top of any ooRexx installation. It replaces the -version of ooDialog in the ooRexx installation with ooDialog 4.2.1. +version of ooDialog in the ooRexx installation with ooDialog 4.2.2. This type of ooDialog installation is called an "independent" ooDialog installation to indicate the ooDialog installation is independent of an ooRexx installation and, to a degree, the version of ooRexx installed. -ooDialog 4.2.1 requires a minimum ooRexx version of 4.1.0. +ooDialog 4.2.2 requires a minimum ooRexx version of 4.1.0. Installation @@ -49,291 +30,77 @@ If the ooRexx version is less than 4.1.0, or if there is no installed ooRexx, the installer will abort with a message explaining the problem. Otherwise the installer will replace the current ooDialog with ooDialog -4.2.1. +4.2.2. Note that the actions of the installer are dependent on the version of ooRexx, not the version of the installed ooDialog. For instance, if the installed ooDialog is version 4.3.0, but for some reason the user is not -happy with that version, running the ooDialog 4.2.1 installer will -replace the 4.3.0 version with the 4.2.1 version. +happy with that version, running the ooDialog 4.2.2 installer will +replace the 4.3.0 version with the 4.2.2 version. At the time of the installation, *all* ooDialog programs must be halted and the ooDialog PDFs must be closed if they happen to be opened. -Changes in ooDialog 4.2.1 since the release of ooDialog 4.2.0 +Changes in ooDialog 4.2.2 since the release of ooDialog 4.2.1 ======================================================================== Bug Fixes in ooDialog: ---------------------- -* #1116 Debug print outs left in ooDialog 4.2.0 -* #1117 Method handler passed wrong argument for TreeView EXPANDING - event -* #1121 ooDialog appcrash running forward class(super) continue - -* #1124 ooDialog - failed to locate .h file message incorrect - -* #1126 ooDialog - args sent to the HELP event handler incorrect - -* #1128 ooDialog UtilityClasses.cls: typo - -* #1138 MessageDialog: Failure in system service - -* #1141 ooDialog - connecting system menu command events can fail - -* #1145 TimedMessage dialog remains on screen after ok() method is - invoked - -* #1146 Return code from ListView::deleteColumn() not as documented - -* #1147 SingleSelection class - -* #1149 Potential crash in ooDialog connectKeyPress() method - - Feature Requests in ooDialog: ----------------------------- -* #42 OODialog List Control Class (report) format individual lines -* #130 OODialog List Control Class Activate sort headers -* #419 Add Tooltip control - -* #420 Would like to have an AddButtonStem method. - -* #478 ooDialog - List-view could use a way to work with a complete row - -* #483 ooDialog setColor and dialog background improvements - -* #484 ooDialog setColor methods should not be restricted to the 19 - palette indexes - -* #485 Treeview itemData - -* #486 ooDialog - the TreeView Expanding event should allow a veto - -* #487 ooDialog - It would be nice if the TreeView class had a way - to do custom sorting - -* #488 ooDialog - TreeView class needs a itemText method - -* #489 ooDialog - TreeView class should support info tips - -* #490 ooDialog - ListView class should support info tips - -* #493 ooDialog - TreeView begin / end label editing could be improved - -* #494 ooDialog - ListView begin / end label editing could be improved - -* #495 ooDialog TreeView control has missing styles - -* #496 ooDialog TreeView methods to determine area occupied by an item - -* #499 ooDialog connectTreeViewEvent CHANGING veto - -* #501 The ListView class should have an easy way to switch views - - New Functionality in ooDialog: ------------------------------ -An implementation that allows acces to the Custom Draw facility in -Microsoft's Common Control library has been added. -Custom Draw allows, for example, the programmer to specify the text and -background colors for individual rows in a ListView, even for individual -columns in the row. The programmer can specify the font of the text for -individual list-view items. Etc., etc.. -The CustomDraw class has been added to ooDialog and is the means to -access the Custom Draw facilities. - -New ListView support classes: ------------------------------ - -LvItem class: - -Represents a single list-view item. The attributes of the LvItem are -the attributes of the underlying Windows list-view item. - -LvSubItem class: - -Represents a single list-view subitem. The attributes of the LvSubItem -are the attributes of the underlying Windows list-view subitem. - -LvFullRow class: - -List-view items can contain subitems. This is most apparent in the row -view of a list-vies where the subitems are displayed in columns next to -the item. However, the subitems, once added to an item, are always -present, even if the list-view is in another view, such as icon view. - -The LvFullRow class represents the list-view item and all its subitems. -LvFullRow objects can be used to insert an item and all data associated -with the item into a list-view at one time. - -LvCustomDrawSimple class: - -The LvCustomDrawSimple class is used in conjuction with the custom draw -facility for ListView controls. - - New dialog classes: ------------------- -CustomDraw class: -The CustomDraw class is a new mixin class. Dialogs in ooDialog can -inherit this class, which then gives the dialog the ability to access -the custom draw facility. -The ListView and TreeView controls can register for custom draw. - - New utility classes: -------------------- -TvCustomDrawSimple class: -The TvCustomDrawSimple class is used in conjuction with the custom draw -facility for TreeView controls. - New Methods: ------------ -In the PlainBaseDialog class: -getTextSizeTitleBar() -In the DialogControl class: - -useVersion() -usingVersion() - -In the ListView class: - -addFullRow() -insertFullRow() -prependFullRow() - -In the TreeView class: - -find() -getItemData() -itemText() -removeItemData() -setItemData() - - New Attributes: --------------- -In the SM (system metrics) class: -cxSize -cxSmIcon -cyMenu - Enhanced Methods: ----------------- -In the DialogControl class: -setColor() -setSysColor() -In the DialogExtensions class: - -setControlColor() -setControlSysColor() - -In the TreeView class: - -insert() -itemInfo() -modify() - -In the EventNotification class: - -connectListViewItem() - - * the KEYDOWNEX event is added. - - * the BEGINEDIT event is enhanced - - * the ENDEDIT event is enhanced - -connectTreeViewItem() - - * the KEYDOWNEX event is added. - - * the BEGINEDIT event is enhanced - - * the ENDEDIT event is enhanced - - New samples: ------------ -oodialog\controls\customDrawListView.rex -The customDrawListView example demonstrates how to change the text, text -color, and background color of individual rows in a list-view. -oodialog\controls\ToolTip\toolTip.rex - -The toolTip.rex example demonstrates the basics of using ToolTips in -ooDialog. It includes the usage of a number of the ToolTip methods. - -oodialog\controls\ToolTip\customPositionToolTip.rex - -The customPositionToolTip.rex example shows how to use the ToolTip class -to do custom positioning of the info tips provided by the tree-view. - -oodialog\controls\ToolTip\manageControlTool.rex - -The manageControlTool.rex example shows how to use some advanced -features of the ToolTip class to provide completely customized ToolTips -for a dialog control. This example uses a tree-view control, but the -techniques could be applied to any dialog control. - - - Enhanced samples: ----------------- -oodialog\treeViewCustomDraw.rex -The oodtree.rex example has been renamed to the treeViewCustomDraw.rex -and enhanced. The example has been more fully commented, uses custom -draw for the tree-view control, and has a number of small bugs fixed. - Documentation: -------------- -The ListView Control chapter in the ooDialog Reference Manual has been -partially reviewed and corrected for accuracy. Parts of the chapter -have been updated to match the format and style that was introduced in -the rework of the manual done for ooDialog 4.2.0 -The TreeView Control chapter in the ooDialog Reference Manual has been -partially reviewed and corrected for accuracy. Parts of the chapter -have been updated to match the format and style that was introduced in -the rework of the manual done for ooDialog 4.2.0 - -The documentation for the connectListViewEvent and connectTreeViewEvent -methods have been enhanced. - - Known Problems, "Gotchas," and Solutions with Independent Installations ======================================================================== Modified: ooDialog/trunk/install/ooDialog.nsi =================================================================== --- ooDialog/trunk/install/ooDialog.nsi 2012-12-13 03:41:51 UTC (rev 8694) +++ ooDialog/trunk/install/ooDialog.nsi 2012-12-13 04:00:18 UTC (rev 8695) @@ -229,7 +229,7 @@ ; Add the files ... File "${ExamplesDir}\controls\TreeView\rc\*.rc" File "${ExamplesDir}\controls\TreeView\rc\*.h" - File "${ExamplesDir}\controls\ListView\rc\*.bmp" + File "${ExamplesDir}\controls\TreeView\rc\*.bmp" ; Set the installation directory: SetOutPath $INSTDIR\samples\oodialog\examples Modified: ooDialog/trunk/ooDialog/ooDialog.ver =================================================================== --- ooDialog/trunk/ooDialog/ooDialog.ver 2012-12-13 03:41:51 UTC (rev 8694) +++ ooDialog/trunk/ooDialog/ooDialog.ver 2012-12-13 04:00:18 UTC (rev 8695) @@ -1,8 +1,8 @@ # This defines the current version of ooDialog OOD_MAJOR=4 OOD_MINOR=2 -OOD_MOD_LVL=1 +OOD_MOD_LVL=2 OOD_BLD_LVL=0 -OOD_VER_STR="4.2.1" +OOD_VER_STR="4.2.2" OOD_COPY_YEAR="2005-2012" |
From: <mie...@us...> - 2012-12-18 03:22:46
|
Revision: 8715 http://sourceforge.net/p/oorexx/code-0/8715 Author: miesfeld Date: 2012-12-18 03:22:43 +0000 (Tue, 18 Dec 2012) Log Message: ----------- Feature request: #504 It would be nice to be able to store a user value as part of the LvFullRow object. See ticket [Feature-Requests:#504] Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/ooDialog/ListView.cls ooDialog/trunk/ooDialog/oodControl.hpp ooDialog/trunk/ooDialog/oodListView.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-17 19:04:19 UTC (rev 8714) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-18 03:22:43 UTC (rev 8715) @@ -53,6 +53,8 @@ Feature Requests in ooDialog: ----------------------------- + * #504 It would be nice to be able to store a user value as part of the + LvFullRow object New Functionality in ooDialog: @@ -80,7 +82,12 @@ --------------- +In the LvFullRow class: +userData The userData attribute allows the programmer to assign any + object to each full row object. + + Enhanced Methods: ----------------- Modified: ooDialog/trunk/ooDialog/ListView.cls =================================================================== --- ooDialog/trunk/ooDialog/ListView.cls 2012-12-17 19:04:19 UTC (rev 8714) +++ ooDialog/trunk/ooDialog/ListView.cls 2012-12-18 03:22:43 UTC (rev 8715) @@ -359,6 +359,9 @@ ::method init external "LIBRARY oodialog lvfr_init" ::method unInit external "LIBRARY oodialog lvfr_unInit" +::attribute userData get external "LIBRARY oodialog lvfr_userData" +::attribute userData set external "LIBRARY oodialog lvfr_setUserData" + ::method addSubItem external "LIBRARY oodialog lvfr_addSubitem" ::method insertSubitem external "LIBRARY oodialog lvfr_insertSubitem" ::method item external "LIBRARY oodialog lvfr_item" Modified: ooDialog/trunk/ooDialog/oodControl.hpp =================================================================== --- ooDialog/trunk/ooDialog/oodControl.hpp 2012-12-17 19:04:19 UTC (rev 8714) +++ ooDialog/trunk/ooDialog/oodControl.hpp 2012-12-18 03:22:43 UTC (rev 8715) @@ -144,6 +144,7 @@ RexxObjectPtr *rxSubItems; // The Rexx subitems rxSubItems[0] is a LvItem, the rest LvSubItems RexxObjectPtr rexxSelf; // The LvFullRow Rexx object RexxObjectPtr bagOfItems; // A Rexx bag to hold the Rexx items and protect from GC + RexxObjectPtr userData; // The user of this class can store an object with each row. HWND hList; // The list-view this full row has been inserted into. uint32_t subItemCount; // The number of subItems uint32_t size; // The allocated size of the subItem array. Modified: ooDialog/trunk/ooDialog/oodListView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-17 19:04:19 UTC (rev 8714) +++ ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-18 03:22:43 UTC (rev 8715) @@ -5682,6 +5682,35 @@ return NULLOBJECT; } +/** LvFullRow::userData [attribute] + */ +RexxMethod1(RexxObjectPtr, lvfr_userData, CSELF, pCSelf) +{ + pCLvFullRow pclvfr = (pCLvFullRow)pCSelf; + if ( pclvfr->userData != NULLOBJECT ) + { + return pclvfr->userData; + } + return TheNilObj; +} +RexxMethod2(RexxObjectPtr, lvfr_setUserData, RexxObjectPtr, obj, CSELF, pCSelf) +{ + pCLvFullRow pclvfr = (pCLvFullRow)pCSelf; + + if ( obj == TheNilObj ) + { + pclvfr->userData = NULL; + context->SetObjectVariable("USERDATA", NULLOBJECT); + } + else + { + pclvfr->userData = obj; + context->SetObjectVariable("USERDATA", obj); + } + + return NULLOBJECT; +} + /** LvFullRow::addSubitem() * * Adds a subitem to this full row. Subitems are always added as the last Modified: ooDialog/trunk/ooDialog/oodPackageEntry.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-12-17 19:04:19 UTC (rev 8714) +++ ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-12-18 03:22:43 UTC (rev 8715) @@ -1112,6 +1112,10 @@ // LvFullRow REXX_METHOD_PROTOTYPE(lvfr_init); REXX_METHOD_PROTOTYPE(lvfr_unInit); +REXX_METHOD_PROTOTYPE(lvfr_userData); +REXX_METHOD_PROTOTYPE(lvfr_setUserData); +REXX_METHOD_PROTOTYPE(lvfr_userData); +REXX_METHOD_PROTOTYPE(lvfr_setUserData); REXX_METHOD_PROTOTYPE(lvfr_addSubitem); REXX_METHOD_PROTOTYPE(lvfr_insertSubitem); REXX_METHOD_PROTOTYPE(lvfr_item); @@ -2132,6 +2136,8 @@ // LvFullRow REXX_METHOD(lvfr_init, lvfr_init), REXX_METHOD(lvfr_unInit, lvfr_unInit), + REXX_METHOD(lvfr_userData, lvfr_userData), + REXX_METHOD(lvfr_setUserData, lvfr_setUserData), REXX_METHOD(lvfr_addSubitem, lvfr_addSubitem), REXX_METHOD(lvfr_insertSubitem, lvfr_insertSubitem), REXX_METHOD(lvfr_item, lvfr_item), |
From: <mie...@us...> - 2012-12-21 00:08:43
|
Revision: 8725 http://sourceforge.net/p/oorexx/code-0/8725 Author: miesfeld Date: 2012-12-21 00:08:40 +0000 (Fri, 21 Dec 2012) Log Message: ----------- Feature requests: #507 ooDialog - Modify the text of a list-view item and all its subitems at one time See ticket [Feature-Requests:#507] #506 Allow modifying a list-view item and all its subitems at once See ticket [Feature-Requests:#506] Modified Paths: -------------- ooDialog/trunk/doc/ReleaseNotes.txt ooDialog/trunk/ooDialog/ListView.cls ooDialog/trunk/ooDialog/oodListView.cpp ooDialog/trunk/ooDialog/oodPackageEntry.cpp Modified: ooDialog/trunk/doc/ReleaseNotes.txt =================================================================== --- ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-20 11:48:01 UTC (rev 8724) +++ ooDialog/trunk/doc/ReleaseNotes.txt 2012-12-21 00:08:40 UTC (rev 8725) @@ -56,7 +56,15 @@ * #504 It would be nice to be able to store a user value as part of the LvFullRow object + * #505 Would like a way to prevent Enter from closing dialog when in + single-line edit control + * #506 Allow modifying a list-view item and all its subitems at once + + * #507 ooDialog - Modify the text of a list-view item and all its + subitems at one time + + New Functionality in ooDialog: ------------------------------ @@ -76,8 +84,21 @@ New Methods: ------------ +In the ListView class: +modifyFullRow Modifies a list-view's item and all its subitem using a + LvFullRow object. +setFullRowText Sets or updates the text for a list-view item and all + its subItems using a LvFullRow object. + +In the Edit class: + +wantReturn Connects the Enter keypress in a single-line edit + control to a method in the Rexx dialog and prevents the + keypress from closing the dialog. + + New Attributes: --------------- Modified: ooDialog/trunk/ooDialog/ListView.cls =================================================================== --- ooDialog/trunk/ooDialog/ListView.cls 2012-12-20 11:48:01 UTC (rev 8724) +++ ooDialog/trunk/ooDialog/ListView.cls 2012-12-21 00:08:40 UTC (rev 8725) @@ -208,6 +208,7 @@ return self~modifyColumnPx(index, label, width, align) ::method modifyColumnPx unguarded external "LIBRARY oodialog lv_modifyColumnPx" +::method modifyFullRow unguarded external "LIBRARY oodialog lv_modifyFullRow" ::method modifyItem unguarded external "LIBRARY oodialog lv_modifyItem" ::method modifySubitem unguarded external "LIBRARY oodialog lv_modifySubitem" ::method next unguarded external "LIBRARY oodialog lv_getNextItem" @@ -246,6 +247,7 @@ return self~setColumnWidthPx(index, width) ::method setColumnWidthPx unguarded external "LIBRARY oodialog lv_setColumnWidthPx" +::method setFullRowText unguarded external "LIBRARY oodialog lv_setFullRowText" ::method setHoverTime unguarded use strict arg time = (-1) if time < -1 then time = -1 Modified: ooDialog/trunk/ooDialog/oodListView.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-20 11:48:01 UTC (rev 8724) +++ ooDialog/trunk/ooDialog/oodListView.cpp 2012-12-21 00:08:40 UTC (rev 8725) @@ -1223,6 +1223,189 @@ /** + * Set the item's, and each subitem's, text to the corresponding value in the + * pclvfr struct. + * + * @param pclvfr + * @param hList + * @param index + * + * @return The true object. + * + * @remarks Originally this function was conceived to be used when the + * list-view item's user data was a full row object and the Rexx + * programmer wanted to sync the list-view item text with what he had + * set the full row object to. + * + * However, it would work well in other circustances. + * + * Contrast this function with the similare updateTextUsingFullRow() + * function. This function unequivocally sets the item and every + * subitem with the text in the full row struct. The other function + * checks for the LVIF_TEXT max and only updates the list-view if the + * mask is set. In addition, it optionally updates the full row + * struct when the item has a full row struct assigned as the user + * data. + */ +static RexxObjectPtr syncFullRowText(pCLvFullRow pclvfr, HWND hList, uint32_t index) +{ + for ( uint32_t i = 0; i <= pclvfr->subItemCount; i++ ) + { + ListView_SetItemText(hList, index, i, (LPSTR)pclvfr->subItems[i]->pszText); + } + return TheTrueObj; +} + + +/** + * Sets the item's and subitem's text to the corresponding value in the pclvfr + * struct. Checks for a LvFullRow object assigned as the user data for the item + * and updates that if needed + * + * @param c + * @param pclvfr + * @param hList + * + * @return The true object. + */ +static RexxObjectPtr updateTextUsingFullRow(RexxMethodContext *c, pCLvFullRow pclvfr, HWND hList) +{ + uint32_t index = pclvfr->subItems[0]->iItem; + + pCLvFullRow pclvfrExisting = maybeGetFullRow(hList, index); + + for ( uint32_t i = 0; i <= pclvfr->subItemCount; i++ ) + { + if ( pclvfr->subItems[i]->mask & LVIF_TEXT ) + { + ListView_SetItemText(hList, index, i, (LPSTR)pclvfr->subItems[i]->pszText); + + if ( pclvfrExisting != NULL ) + { + updateFullRowText(c->threadContext, pclvfrExisting, i, pclvfr->subItems[i]->pszText); + } + } + } + return TheTrueObj; +} + + +/** + * Set the item's, and each subitem's, values to the corresponding values in the + * pclvfr struct. + * + * @param pclvfr + * @param hList + * @param index + * + * @return True on success, false if an error occurs with ListView_SetItem(). + * + * @remarks Originally this function was conceived to be used when the + * list-view item's user data was a full row object and the Rexx + * programmer wanted to sync the list-view item text with what he had + * set the full row object to. + * + * However, it would work well in other circustances, *if*, there is + * no full row user data assigned to the list-view item that needs to + * be updated. + */ +static RexxObjectPtr syncFullRow(pCLvFullRow pclvfr, HWND hList, uint32_t index) +{ + for ( uint32_t i = 0; i <= pclvfr->subItemCount; i++ ) + { + if ( ! ListView_SetItem(hList, pclvfr->subItems[i]) ) + { + return TheFalseObj; + } + } + return TheTrueObj; +} + + +/** + * Sets the item's and subitem's values to the corresponding values in the + * pclvfr struct. Checks for a LvFullRow object assigned as the user data for + * the item and updates that if needed + * + * @param c + * @param pclvfr + * @param hList + * + * @return The true object. + * + * @remarks There are 3 scenarios we have to manage here. + * + * 1.) There is no current lParam user data set. In this case the + * lvItem is just used as is to do a set item. If a lParam user data + * value is set, we need to protect it. + * + * 2.) There is a current lParam user data set, but it is not a full + * row object. In this case, if lvItem contains a lParam user data + * value, we need to replace the current value with the new value. + * + * 3.) There is a current lParam user data set and it is a full row + * object. In this case, if lvItem contains a lParm user data value + * we need to update the current value with the new value. If not, + * we need to merge the new lvItem into the full row item. + */ +static RexxObjectPtr modifyFullRow(RexxMethodContext *c, pCDialogControl pcdc, pCLvFullRow pclvfr, HWND hList) +{ + uint32_t index = pclvfr->subItems[0]->iItem; + + RexxObjectPtr oldUserData = getCurrentLviUserData(hList, index); + pCLvFullRow pclvfrExisting = maybeGetFullRow(hList, index); + bool lParamIsModified = (pclvfr->subItems[0]->mask & LVIF_PARAM) ? true : false; + + for ( uint32_t i = 0; i <= pclvfr->subItemCount; i++ ) + { + LPLVITEM pLvi = pclvfr->subItems[i]; + + if ( ! ListView_SetItem(hList, pLvi) ) + { + return TheFalseObj; + } + + if ( i == 0 ) + { + if ( lParamIsModified ) + { + protectLviUserData(c, pcdc, pLvi); + } + + if ( oldUserData != TheNilObj ) + { + if ( lParamIsModified ) + { + unProtectControlUserData(c, pcdc, oldUserData); + } + else if ( pclvfrExisting != NULL ) + { + mergeLviState(c, pclvfrExisting, pclvfrExisting->subItems[0], pLvi); + } + } + } + else + { + if ( pclvfrExisting != NULL && pclvfrExisting->subItemCount >= i ) + { + if ( pLvi->mask & LVIF_TEXT ) + { + updateFullRowText(c->threadContext, pclvfrExisting, i, pLvi->pszText); + } + + if ( pLvi->mask & LVIF_IMAGE ) + { + pclvfr->subItems[i]->iImage = pLvi->iImage; + } + } + } + } + + return TheTrueObj; +} + + +/** * Adds an item to the list view using a LvFullRow object. The item is * inserted, appended, or prepended to the list, as specified by the FullRowOp * type. @@ -3416,6 +3599,63 @@ return TheNegativeOneObj; } +/** ListView::modifyFullRow() + * + * Modifies a full row of a list-view item as specified. That is, modifies the + * item and all subitems, if any, of the list-view item. + * + * @param row [required] This argument can be either the index of the item to + * update, or a LvFullRow object to do the update with. + * + * When row is an index, then the item data for the row *must* be a + * LvFullRow object. Using an index signals that the row has + * already been updated and the programmer wants the list-view item + * "synched" with the full row. + * + * When row is a LvFullRow object, then the underlying list-view + * item's values are set to the full row object's values. Also, + * for this case, if the item being updated also has a full row + * object assigned the item data, that full row object's values are + * updated, or merged, with the sent full row object's values. + * + * @return True on success, false on error. + */ +RexxMethod2(RexxObjectPtr, lv_modifyFullRow, OPTIONAL_RexxObjectPtr, row, CSELF, pCSelf) +{ + RexxObjectPtr result = TheFalseObj; + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + + if ( pcdc == NULL ) + { + goto done_out; + } + + uint32_t index; + HWND hList = pcdc->hCtrl; + + if ( context->IsOfType(row, "LVFULLROW") ) + { + result = modifyFullRow(context, pcdc, (pCLvFullRow)context->ObjectToCSelf(row), hList); + } + else if ( context->UnsignedInt32(row, &index) ) + { + pCLvFullRow pclvfr = maybeGetFullRow(hList, index); + if ( pclvfr == NULL ) + { + userDefinedMsgException(context, 1, "the item data for the list-view item is not a LvFullRow object"); + goto done_out; + } + result = syncFullRow(pclvfr, hList, index); + } + else + { + wrongArgValueException(context->threadContext, 1, "a LvFullRow object or the list-view item index", row); + } + +done_out: + return result; +} + /** ListView::modifyItem() * * Modifies a list-view item using a LvItem object. @@ -3796,6 +4036,63 @@ return (ListView_SetColumnWidth(hList, index, width) ? TheZeroObj : TheOneObj); } +/** ListView::setFullRowText() + * + * Sets the text for the specified item and all subitems. + * + * @param row [required] This argument can be either the index of the item to + * update, or a LvFullRow object to do the update with. + * + * When row is an index, then the item data for the row *must* be a + * LvFullRow object. Using an index signals that the text in the + * full row has already been updated and the programmer wants the + * list-view item "synched" with the text in the full row. + * + * When row is a LvFullRow object, then the underlying list-view + * item's text is set to the text in the full row object. Only + * the item and subitems that have the TEXT mask set are updated. + * Also, for this case, if the item being updated also has a full + * row object assigned the item data, that full row object's text + * is updated + * + * @return True on success, false on error. + */ +RexxMethod2(RexxObjectPtr, lv_setFullRowText, OPTIONAL_RexxObjectPtr, row, CSELF, pCSelf) +{ + RexxObjectPtr result = TheFalseObj; + pCDialogControl pcdc = validateDCCSelf(context, pCSelf); + + if ( pcdc == NULL ) + { + goto done_out; + } + + uint32_t index; + HWND hList = pcdc->hCtrl; + + if ( context->IsOfType(row, "LVFULLROW") ) + { + result = updateTextUsingFullRow(context, (pCLvFullRow)context->ObjectToCSelf(row), hList); + } + else if ( context->UnsignedInt32(row, &index) ) + { + pCLvFullRow pclvfr = maybeGetFullRow(hList, index); + if ( pclvfr == NULL ) + { + userDefinedMsgException(context, 1, "the item data for the list-view item is not a LvFullRow object"); + goto done_out; + } + result = syncFullRowText(pclvfr, hList, index); + } + else + { + wrongArgValueException(context->threadContext, 1, "a LvFullRow object or the list-view item index", row); + } + +done_out: + return result; +} + /** ListView::setImageList() * * Sets or removes one of a list-view's image lists. Modified: ooDialog/trunk/ooDialog/oodPackageEntry.cpp =================================================================== --- ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-12-20 11:48:01 UTC (rev 8724) +++ ooDialog/trunk/ooDialog/oodPackageEntry.cpp 2012-12-21 00:08:40 UTC (rev 8725) @@ -1045,6 +1045,7 @@ REXX_METHOD_PROTOTYPE(lv_itemText); REXX_METHOD_PROTOTYPE(lv_modify); REXX_METHOD_PROTOTYPE(lv_modifyColumnPx); +REXX_METHOD_PROTOTYPE(lv_modifyFullRow); REXX_METHOD_PROTOTYPE(lv_modifyItem); REXX_METHOD_PROTOTYPE(lv_modifySubitem); REXX_METHOD_PROTOTYPE(lv_prependFullRow); @@ -1054,6 +1055,7 @@ REXX_METHOD_PROTOTYPE(lv_setColor); REXX_METHOD_PROTOTYPE(lv_setColumnOrder); REXX_METHOD_PROTOTYPE(lv_setColumnWidthPx); +REXX_METHOD_PROTOTYPE(lv_setFullRowText); REXX_METHOD_PROTOTYPE(lv_setImageList); REXX_METHOD_PROTOTYPE(lv_setItemData); REXX_METHOD_PROTOTYPE(lv_setItemPos); @@ -2069,6 +2071,7 @@ REXX_METHOD(lv_itemState, lv_itemState), REXX_METHOD(lv_modify, lv_modify), REXX_METHOD(lv_modifyColumnPx, lv_modifyColumnPx), + REXX_METHOD(lv_modifyFullRow, lv_modifyFullRow), REXX_METHOD(lv_modifyItem, lv_modifyItem), REXX_METHOD(lv_modifySubitem, lv_modifySubitem), REXX_METHOD(lv_prependFullRow, lv_prependFullRow), @@ -2078,6 +2081,7 @@ REXX_METHOD(lv_setColor, lv_setColor), REXX_METHOD(lv_setColumnOrder, lv_setColumnOrder), REXX_METHOD(lv_setColumnWidthPx, lv_setColumnWidthPx), + REXX_METHOD(lv_setFullRowText, lv_setFullRowText), REXX_METHOD(lv_setImageList, lv_setImageList), REXX_METHOD(lv_setItemData, lv_setItemData), REXX_METHOD(lv_setItemPos, lv_setItemPos), |
From: <mie...@us...> - 2013-01-05 06:08:11
|
Revision: 8774 http://sourceforge.net/p/oorexx/code-0/8774 Author: miesfeld Date: 2013-01-05 06:08:06 +0000 (Sat, 05 Jan 2013) Log Message: ----------- Feature request: #249 Add support for generalized resizable dialogs See ticket [Feature-Requests:#249] Modified Paths: -------------- ooDialog/trunk/examples/Makefile.am ooDialog/trunk/ooDialog/oodResizableDialog.cpp Added Paths: ----------- ooDialog/trunk/examples/resizableDialogs/ ooDialog/trunk/examples/resizableDialogs/DialogAreaU/ ooDialog/trunk/examples/resizableDialogs/DialogAreaU/Makefile.am ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemo.h ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemo.rex ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemoThree.rex ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemoTwo.rex ooDialog/trunk/examples/resizableDialogs/Makefile.am ooDialog/trunk/examples/resizableDialogs/ReadMe.txt ooDialog/trunk/examples/resizableDialogs/ResizingAdmin/ ooDialog/trunk/examples/resizableDialogs/ResizingAdmin/Makefile.am ooDialog/trunk/examples/resizableDialogs/ResizingAdmin/augmentedResize.rex ooDialog/trunk/examples/resizableDialogs/ResizingAdmin/basicResize.h ooDialog/trunk/examples/resizableDialogs/ResizingAdmin/basicResize.rc ooDialog/trunk/examples/resizableDialogs/ResizingAdmin/basicResize.rex Removed Paths: ------------- ooDialog/trunk/examples/dlgAreaUDemo.h ooDialog/trunk/examples/dlgAreaUDemo.rex ooDialog/trunk/examples/dlgAreaUDemoThree.rex ooDialog/trunk/examples/dlgAreaUDemoTwo.rex Modified: ooDialog/trunk/examples/Makefile.am =================================================================== --- ooDialog/trunk/examples/Makefile.am 2013-01-04 19:03:20 UTC (rev 8773) +++ ooDialog/trunk/examples/Makefile.am 2013-01-05 06:08:06 UTC (rev 8774) @@ -37,8 +37,8 @@ .NOTPARALLEL: -SUBDIRS = bmp controls examples menus mouse oleinfo ooRexxTry propertySheet.tabControls rc res simple sysinfo tutorial userGuide wav winsystem -DIST_SUBDIRS = bmp controls examples menus mouse oleinfo ooRexxTry propertySheet.tabControls rc res simple sysinfo tutorial userGuide wav winsystem +SUBDIRS = bmp controls examples menus mouse oleinfo ooRexxTry propertySheet.tabControls rc res resizableDialogs simple sysinfo tutorial userGuide wav winsystem +DIST_SUBDIRS = bmp controls examples menus mouse oleinfo ooRexxTry propertySheet.tabControls rc res resizableDialogs simple sysinfo tutorial userGuide wav winsystem MAINTAINERCLEANFILES = Makefile.in *~ Deleted: ooDialog/trunk/examples/dlgAreaUDemo.h =================================================================== --- ooDialog/trunk/examples/dlgAreaUDemo.h 2013-01-04 19:03:20 UTC (rev 8773) +++ ooDialog/trunk/examples/dlgAreaUDemo.h 2013-01-05 06:08:06 UTC (rev 8774) @@ -1,51 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* */ -/* Copyright (c) 2010-2013 Rexx Language Association. All rights reserved. */ -/* */ -/* This program and the accompanying materials are made available under */ -/* the terms of the Common Public License v1.0 which accompanies this */ -/* distribution. A copy is also available at the following address: */ -/* http://www.oorexx.org/license.html */ -/* */ -/* Redistribution and use in source and binary forms, with or */ -/* without modification, are permitted provided that the following */ -/* conditions are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* Redistributions in binary form must reproduce the above copyright */ -/* notice, this list of conditions and the following disclaimer in */ -/* the documentation and/or other materials provided with the distribution. */ -/* */ -/* Neither the name of Rexx Language Association nor the names */ -/* of its contributors may be used to endorse or promote products */ -/* derived from this software without specific prior written permission. */ -/* */ -/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ -/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ -/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ -/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ -/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ -/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ -/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ -/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/*----------------------------------------------------------------------------*/ - -/* - * Symbolic resource IDs for the dlgAreaUDemo (dlgAreUDemo.rex and - * dlgAreaUDemoTwo.rex) programs. - */ - -#define IDC_ST_STATUS 111 -#define IDC_EDIT 112 -#define IDC_PB_0 113 -#define IDC_PB_1 114 -#define IDC_PB_2 115 -#define IDC_PB_3 116 -#define IDC_PB_4 117 -#define IDC_PB_5 118 -#define IDC_PB_6 119 Deleted: ooDialog/trunk/examples/dlgAreaUDemo.rex =================================================================== --- ooDialog/trunk/examples/dlgAreaUDemo.rex 2013-01-04 19:03:20 UTC (rev 8773) +++ ooDialog/trunk/examples/dlgAreaUDemo.rex 2013-01-05 06:08:06 UTC (rev 8774) @@ -1,100 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* */ -/* Copyright (c) 2006-2013 Rexx Language Association. All rights reserved. */ -/* */ -/* This program and the accompanying materials are made available under */ -/* the terms of the Common Public License v1.0 which accompanies this */ -/* distribution. A copy is also available at the following address: */ -/* http://www.oorexx.org/license.html */ -/* */ -/* Redistribution and use in source and binary forms, with or */ -/* without modification, are permitted provided that the following */ -/* conditions are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* Redistributions in binary form must reproduce the above copyright */ -/* notice, this list of conditions and the following disclaimer in */ -/* the documentation and/or other materials provided with the distribution. */ -/* */ -/* Neither the name of Rexx Language Association nor the names */ -/* of its contributors may be used to endorse or promote products */ -/* derived from this software without specific prior written permission. */ -/* */ -/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ -/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ -/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ -/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ -/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ -/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ -/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ -/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/*----------------------------------------------------------------------------*/ -/* DlgAreaDemo.Rex -- Demonstrate DlgArea & DlgAreaU Classes -- Feb 2006 */ - -.application~useGlobalConstDir("O", 'dlgAreaUDemo.h') - -MyDlg=.MyDialog~new -MyDlg~execute('ShowTop') - -return 0 - -::requires "ooDialog.cls" -/* ========================================================================= */ -::class MyDialog Subclass UserDialog -/* ========================================================================= */ -::method init -/* ------------------------------------------------------------------------- */ - forward class (super) continue - success=self~createCenter(250,250,'My Resizable Dialog',, - 'ThickFrame MinimizeBox MaximizeBox',,, - 'MS Sans Serif',8) - if \success then do - self~initCode = 1 - return - end - - self~connectResize('OnResize', .true) - -/* ------------------------------------------------------------------------- */ -::method defineDialog -/* ------------------------------------------------------------------------- */ -expose u - -u=.dlgAreaU~new(self) /* whole dlg */ -if u~lastError \= .nil then call errorDialog u~lastError - -u~noResizePut(IDC_PB_0) -e=.dlgArea~new(u~x , u~y , u~w('70%'), u~h('90%')) /* edit area */ -s=.dlgArea~new(u~x , u~y('90%'), u~w('70%'), u~hr ) /* status area */ -b=.dlgArea~new(u~x('70%'), u~y , u~wr , u~hr ) /* button area */ - -self~createEdit(IDC_EDIT, e~x, e~y, e~w, e~h, 'multiline', 'text') -self~createStaticText(IDC_ST_STATUS, s~x, s~y, s~w, s~h, , 'Status info appears here') - -self~createPushButton(IDC_PB_0, b~x, b~y('00%'), b~w, b~h('9%'), , 'Button' 0, 'Button'||0) -self~createPushButton(IDC_PB_1, b~x, b~y('10%'), b~w, b~h('9%'), , 'Button' 1, 'Button'||1) -self~createPushButton(IDC_PB_2, b~x, b~y('20%'), b~w, b~h('9%'), , 'Button' 2, 'Button'||2) -self~createPushButton(IDC_PB_3, b~x, b~y('30%'), b~w, b~h('9%'), , 'Button' 3, 'Button'||3) -self~createPushButton(IDC_PB_4, b~x, b~y('40%'), b~w, b~h('9%'), , 'Button' 4, 'Button'||4) -self~createPushButton(IDC_PB_5, b~x, b~y('50%'), b~w, b~h('9%'), , 'Button' 5, 'Button'||5) -self~createPushButton(IDC_PB_6, b~x, b~y('60%'), b~w, b~h('9%'), , 'Button' 6, 'Button'||6) -self~createPushButton(IDOK, b~x, b~y('90%'), b~w, b~h('9%'), 'DEFAULT', 'Ok') - -/* ------------------------------------------------------------------------- */ -::method onResize -/* ------------------------------------------------------------------------- */ -expose u -use arg dummy,sizeinfo -u~resize(self,sizeinfo) - -/* ------------------------------------------------------------------------- */ -::method unknown -/* ------------------------------------------------------------------------- */ -use arg msgname, args -if msgname~abbrev("BUTTON") then - self~newStatic(IDC_ST_STATUS)~setText('You Pressed Button' msgname~right(1)) Deleted: ooDialog/trunk/examples/dlgAreaUDemoThree.rex =================================================================== --- ooDialog/trunk/examples/dlgAreaUDemoThree.rex 2013-01-04 19:03:20 UTC (rev 8773) +++ ooDialog/trunk/examples/dlgAreaUDemoThree.rex 2013-01-05 06:08:06 UTC (rev 8774) @@ -1,281 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* */ -/* Copyright (c) 2006-2013 Rexx Language Association. All rights reserved. */ -/* */ -/* This program and the accompanying materials are made available under */ -/* the terms of the Common Public License v1.0 which accompanies this */ -/* distribution. A copy is also available at the following address: */ -/* http://www.oorexx.org/license.html */ -/* */ -/* Redistribution and use in source and binary forms, with or */ -/* without modification, are permitted provided that the following */ -/* conditions are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* Redistributions in binary form must reproduce the above copyright */ -/* notice, this list of conditions and the following disclaimer in */ -/* the documentation and/or other materials provided with the distribution. */ -/* */ -/* Neither the name of Rexx Language Association nor the names */ -/* of its contributors may be used to endorse or promote products */ -/* derived from this software without specific prior written permission. */ -/* */ -/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ -/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ -/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ -/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ -/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ -/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ -/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ -/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/*----------------------------------------------------------------------------*/ - -/** - * DlgAreaDemoThree.Rex - * - * Demonstrates a second approach to resizable dialogs. Essentially what this - * approach does is to defer the redrawing of the dialog controls until the - * user has finished resizing the dialog. - * - * This example is exactly like DlgAreaDemoTwo.rex, except it also demonstrates - * how to prevent the user from resizing the dialog smaller than a minimum - * size. Look at the connectResizing() method in init() and the onResizing() - * method for the code that does this. - * - * To better understand this example completely, please read the header - * comments in the DlgAreaDemoTwo.rex example. - */ - - .application~useGlobalConstDir("O", 'dlgAreaUDemo.h') - - dlg = .ResizableDialog~new - dlg~execute('ShowTop') - - return 0 - -::requires "ooDialog.cls" - -::class 'ResizableDialog' subclass UserDialog - -::method init - - forward class (super) continue - success = self~createCenter(250, 250, 'My Flicker Free Resizable Dialog', - - 'ThickFrame MinimizeBox MaximizeBox', , - - 'MS Sans Serif', 8) - if \ success then do - self~initCode = 1 - return - end - - self~connectResize('onResize', .true) - self~connectResizing('onResizing') - self~connectSizeMoveEnded('onSizeMoveEnded') - - -::method defineDialog - expose u sizing minMaximized - - u = .dlgAreaU~new(self) - if u~lastError \= .nil then call errorDialog u~lastError - - -- Tell the DialogAreaU object to not invoke the update method. - u~updateOnResize = .false - - -- We use these variables to track when to redraw, or not. - sizing = .false - minMaximized = .false - - u~noResizePut(IDC_PB_0) - e = .dlgArea~new(u~x , u~y , u~w('70%'), u~h('90%')) -- edit area - s = .dlgArea~new(u~x , u~y('90%'), u~w('70%'), u~hr ) -- status area - b = .dlgArea~new(u~x('70%'), u~y , u~wr , u~hr ) -- button area - - self~createEdit('IDC_EDIT', e~x, e~y, e~w, e~h, 'multiline') - self~createStaticText('IDC_ST_STATUS', s~x, s~y, s~w, s~h, , 'Status info appears here') - - self~createPushButton('IDC_PB_0', b~x, b~y('00%'), b~w, b~h('9%'), , 'Button' 0 , 'Button'||0) - self~createPushButton('IDC_PB_1', b~x, b~y('10%'), b~w, b~h('9%'), , 'Button' 1 , 'Button'||1) - self~createPushButton('IDC_PB_2', b~x, b~y('20%'), b~w, b~h('9%'), , 'Button' 2 , 'Button'||2) - self~createPushButton('IDC_PB_3', b~x, b~y('30%'), b~w, b~h('9%'), , 'Button' 3 , 'Button'||3) - self~createPushButton('IDC_PB_4', b~x, b~y('40%'), b~w, b~h('9%'), , 'Button' 4 , 'Button'||4) - self~createPushButton('IDC_PB_5', b~x, b~y('50%'), b~w, b~h('9%'), , 'Button' 5 , 'Button'||5) - self~createPushButton('IDC_PB_6', b~x, b~y('60%'), b~w, b~h('9%'), , 'Button' 6 , 'Button'||6) - self~createPushButton('IDOK', b~x, b~y('90%'), b~w, b~h('9%'), 'DEFAULT', 'Ok') - - -::method initDialog - expose minWidth minHeight - - -- The underlying edit controls internally resize themselves as the dialog - -- they are contained in is resized. We don't want that, so we disable that - -- behavior in the underlying edit control. - self~newEdit(IDC_EDIT)~disableInternalResize - - -- We will restrict the minimum width and minimum height to our original - -- width and height - minWidth = self~pixelCX - minHeight = self~pixelCY - - --- The RESIZING event happens when the user is resizing the dialog, but *before* --- the size of the dialog is actually changed. The first arg is a .RECT object --- that describes the new size. If we change the coordinates in the rectangle, --- and reply .true. The new size of the dialog will be our changed coordinates. --- --- Here, if the new size is smaller than we want, we just change the rectangle --- coordinates to our minimum size. The 'direction' argument tells us which --- edge of the dialog the user is dragging. We use that to decide which --- coordinate(s) to change. --- --- A maximum size for the dialog could be enforced in a similar way. -::method onResizing unguarded - expose minWidth minHeight - use arg r, direction - - select - when direction == 'TOP' then do - if r~bottom - r~top < minHeight then do - r~top = r~bottom - minHeight - return .true - end - end - when direction == 'BOTTOM' then do - if r~bottom - r~top < minHeight then do - r~bottom = r~top + minHeight - return .true - end - end - when direction == 'LEFT' then do - if r~right - r~left < minWidth then do - r~left = r~right - minWidth - return .true - end - end - when direction == 'RIGHT' then do - if r~right - r~left < minWidth then do - r~right = r~left + minWidth - return .true - end - end - when direction == 'BOTTOMLEFT' then do - didChange = .false - - if r~bottom - r~top < minHeight then do - r~bottom = r~top + minHeight - didChange = .true - end - - if r~right - r~left < minWidth then do - r~left = r~right - minWidth - didChange = .true - end - - return didChange - end - when direction == 'BOTTOMRIGHT' then do - didChange = .false - - if r~bottom - r~top < minHeight then do - r~bottom = r~top + minHeight - didChange = .true - end - - if r~right - r~left < minWidth then do - r~right = r~left + minWidth - didChange = .true - end - - return didChange - end - when direction == 'TOPLEFT' then do - didChange = .false - - if r~bottom - r~top < minHeight then do - r~top = r~bottom - minHeight - didChange = .true - end - - if r~right - r~left < minWidth then do - r~left = r~right - minWidth - didChange = .true - end - - return didChange - end - when direction == 'TOPRIGHT' then do - didChange = .false - - if r~bottom - r~top < minHeight then do - r~top = r~bottom - minHeight - didChange = .true - end - - if r~right - r~left < minWidth then do - r~right = r~left + minWidth - didChange = .true - end - - return didChange - end - otherwise - nop - end - -- End select - return .false - -::method onResize unguarded - expose u sizing minMaximized lastSizeInfo - use arg sizingType, sizeinfo - - -- Save the size information so we know the final size of the dialog. - lastSizeInfo = sizeInfo - - -- The size / move ended event does not occur when the user maximizes, - -- minimizes, or restores from maximized / minimized. Because of that, we - -- need to redraw the client area under those conditions. - - if sizingType == self~SIZE_MAXIMIZED | sizingType == self~SIZE_MINIMIZED then do - minMaximized = .true - if sizingType == self~SIZE_MAXIMIZED then do - u~resize(self, sizeinfo) - self~redrawClient(.true) - end - end - else if sizingType == self~SIZE_RESTORED, minMaximized then do - minMaximized = .false - u~resize(self, sizeinfo) - self~redrawClient(.true) - end - else do - -- We are resizing now. - sizing = .true - end - - return 0 - - -::method onSizeMoveEnded unguarded - expose u sizing lastSizeInfo - - -- If we were resizing, force the dialog controls to redraw themselves. - if sizing then do - u~resize(self, lastSizeInfo) - self~redrawClient(.true) - end - - -- We are not resizing anymore. - sizing = .false - return 0 - - -::method unknown - use arg msgName, args - - if msgName~abbrev("BUTTON") then - self~newStatic(IDC_ST_STATUS)~setText('You Pressed Button' msgName~right(1)) Deleted: ooDialog/trunk/examples/dlgAreaUDemoTwo.rex =================================================================== --- ooDialog/trunk/examples/dlgAreaUDemoTwo.rex 2013-01-04 19:03:20 UTC (rev 8773) +++ ooDialog/trunk/examples/dlgAreaUDemoTwo.rex 2013-01-05 06:08:06 UTC (rev 8774) @@ -1,193 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* */ -/* Copyright (c) 2006-2013 Rexx Language Association. All rights reserved. */ -/* */ -/* This program and the accompanying materials are made available under */ -/* the terms of the Common Public License v1.0 which accompanies this */ -/* distribution. A copy is also available at the following address: */ -/* http://www.oorexx.org/license.html */ -/* */ -/* Redistribution and use in source and binary forms, with or */ -/* without modification, are permitted provided that the following */ -/* conditions are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* Redistributions in binary form must reproduce the above copyright */ -/* notice, this list of conditions and the following disclaimer in */ -/* the documentation and/or other materials provided with the distribution. */ -/* */ -/* Neither the name of Rexx Language Association nor the names */ -/* of its contributors may be used to endorse or promote products */ -/* derived from this software without specific prior written permission. */ -/* */ -/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ -/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ -/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ -/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ -/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ -/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ -/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ -/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/*----------------------------------------------------------------------------*/ - -/** - * DlgAreaDemoTwo.Rex - * - * Demonstrates a second approach to resizable dialogs. Essentially what this - * approach does is to defer the redrawing of the dialog controls until the - * user has finished resizing the dialog. - * - * By default, the DialogAreaU class calls a dialog method (the update method) - * that forces all the dialog controls to redraw themselves every time a resize - * event ocurrs. This causes the constant flicker seen in DlgAreaDemo.rex. - * - * The approach taken here is to tell the DialogAreaU object to *not* invoke - * the update method during the resize event. This is done by setting the - * updateOnResize attribute to false in the DialogAreaU object. - * - * Then we connect the size / move ended event to a method in our dialog. This - * event is called exactly once when the user has stopped resizing or moving - * the dialog. - * - * We keep track of whether the user is resizing, or not. When we get the size - * move ended event, if the user was resizing, we invoke the redrawClient - * method of the dialog, forcing all the dialog controls to redraw themselves - * in their new, final, position. - * - * This eliminates the flicker, but also makes it appear as though the dialog - * controls are not changing while the user is actively resizing. When the - * user stops resizing, the dialog controls "magically" appear in their new - * size and position. - * - * Which approach is better is probably a matter of personal preference. - * - * After some use of this example program, a refinement to the above algorithm - * was made. This is what is used now. Since no repainting of the dialog - * controls is done until the last resize event, there is no sense in re- - * calculating the size and position of each control on every resize event. - * - * Rather than invoke u~resize(self, sizeinfo) every single time in onResize() - * u~resize is only invoked when the dialog client area is going to be forced - * to redraw. - */ - - .application~useGlobalConstDir("O", 'dlgAreaUDemo.h') - - dlg = .ResizableDialog~new - dlg~execute('ShowTop') - - return 0 - -::requires "ooDialog.cls" - -::class 'ResizableDialog' subclass UserDialog - -::method init - - forward class (super) continue - success = self~createCenter(250, 250, 'My Flicker Free Resizable Dialog', - - 'ThickFrame MinimizeBox MaximizeBox', , - - 'MS Sans Serif', 8) - if \ success then do - self~initCode = 1 - return - end - - self~connectResize('onResize', .true) - self~connectSizeMoveEnded('onSizeMoveEnded') - - -::method defineDialog - expose u sizing minMaximized - - u = .dlgAreaU~new(self) - if u~lastError \= .nil then call errorDialog u~lastError - - -- Tell the DialogAreaU object to not invoke the update method. - u~updateOnResize = .false - - -- We use these variables to track when to redraw, or not. - sizing = .false - minMaximized = .false - - u~noResizePut(IDC_PB_0) - e = .dlgArea~new(u~x , u~y , u~w('70%'), u~h('90%')) -- edit area - s = .dlgArea~new(u~x , u~y('90%'), u~w('70%'), u~hr ) -- status area - b = .dlgArea~new(u~x('70%'), u~y , u~wr , u~hr ) -- button area - - self~createEdit(IDC_EDIT, e~x, e~y, e~w, e~h, 'multiline') - self~createStaticText(IDC_ST_STATUS, s~x, s~y, s~w, s~h, , 'Status info appears here') - - self~createPushButton(IDC_PB_0, b~x, b~y('00%'), b~w, b~h('9%'), , 'Button' 0 , 'Button'||0) - self~createPushButton(IDC_PB_1, b~x, b~y('10%'), b~w, b~h('9%'), , 'Button' 1 , 'Button'||1) - self~createPushButton(IDC_PB_2, b~x, b~y('20%'), b~w, b~h('9%'), , 'Button' 2 , 'Button'||2) - self~createPushButton(IDC_PB_3, b~x, b~y('30%'), b~w, b~h('9%'), , 'Button' 3 , 'Button'||3) - self~createPushButton(IDC_PB_4, b~x, b~y('40%'), b~w, b~h('9%'), , 'Button' 4 , 'Button'||4) - self~createPushButton(IDC_PB_5, b~x, b~y('50%'), b~w, b~h('9%'), , 'Button' 5 , 'Button'||5) - self~createPushButton(IDC_PB_6, b~x, b~y('60%'), b~w, b~h('9%'), , 'Button' 6 , 'Button'||6) - self~createPushButton(IDOK, b~x, b~y('90%'), b~w, b~h('9%'), 'DEFAULT', 'Ok') - - -::method initDialog - - -- The underlying edit controls internally resize themselves as the dialog - -- they are contained in is resized. We don't want that, so we disable that - -- behavior in the underlying edit control. - self~newEdit(IDC_EDIT)~disableInternalResize - - -::method onResize unguarded - expose u sizing minMaximized lastSizeInfo - use arg sizingType, sizeinfo - - -- Save the size information so we know the final size of the dialog. - lastSizeInfo = sizeInfo - - -- The size / move ended event does not occur when the user maximizes, - -- minimizes, or restores from maximized / minimized. Because of that, we - -- need to redraw the client area under those conditions. - - if sizingType == self~SIZE_MAXIMIZED | sizingType == self~SIZE_MINIMIZED then do - minMaximized = .true - if sizingType == self~SIZE_MAXIMIZED then do - u~resize(self, sizeinfo) - self~redrawClient(.true) - end - end - else if sizingType == self~SIZE_RESTORED, minMaximized then do - minMaximized = .false - u~resize(self, sizeinfo) - self~redrawClient(.true) - end - else do - -- We are resizing now. - sizing = .true - end - - return 0 - - -::method onSizeMoveEnded unguarded - expose u sizing lastSizeInfo - - -- If we were resizing, force the dialog controls to redraw themselves. - if sizing then do - u~resize(self, lastSizeInfo) - self~redrawClient(.true) - end - - -- We are not resizing anymore. - sizing = .false - return 0 - - -::method unknown - use arg msgName, args - - if msgName~abbrev("BUTTON") then - self~newStatic(IDC_ST_STATUS)~setText('You Pressed Button' msgName~right(1)) Copied: ooDialog/trunk/examples/resizableDialogs/DialogAreaU/Makefile.am (from rev 8773, ooDialog/trunk/examples/rc/Makefile.am) =================================================================== --- ooDialog/trunk/examples/resizableDialogs/DialogAreaU/Makefile.am (rev 0) +++ ooDialog/trunk/examples/resizableDialogs/DialogAreaU/Makefile.am 2013-01-05 06:08:06 UTC (rev 8774) @@ -0,0 +1,43 @@ +#/*----------------------------------------------------------------------------*/ +#/* */ +#/* Copyright (c) 2005-2013 Rexx Language Association. All rights reserved. */ +#/* */ +#/* This program and the accompanying materials are made available under */ +#/* the terms of the Common Public License v1.0 which accompanies this */ +#/* distribution. A copy is also available at the following address: */ +#/* http://www.oorexx.org/license.html */ +#/* */ +#/* Redistribution and use in source and binary forms, with or */ +#/* without modification, are permitted provided that the following */ +#/* conditions are met: */ +#/* */ +#/* Redistributions of source code must retain the above copyright */ +#/* notice, this list of conditions and the following disclaimer. */ +#/* Redistributions in binary form must reproduce the above copyright */ +#/* notice, this list of conditions and the following disclaimer in */ +#/* the documentation and/or other materials provided with the distribution. */ +#/* */ +#/* Neither the name of Rexx Language Association nor the names */ +#/* of its contributors may be used to endorse or promote products */ +#/* derived from this software without specific prior written permission. */ +#/* */ +#/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +#/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +#/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +#/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +#/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +#/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +#/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +#/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +#/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +#/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +#/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#/* */ +#/*----------------------------------------------------------------------------*/ + +.NOTPARALLEL: + +MAINTAINERCLEANFILES = Makefile.in *~ + +EXTRA_DIST = *.rex *.h + Copied: ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemo.h (from rev 8773, ooDialog/trunk/examples/dlgAreaUDemo.h) =================================================================== --- ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemo.h (rev 0) +++ ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemo.h 2013-01-05 06:08:06 UTC (rev 8774) @@ -0,0 +1,51 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2010-2013 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/* + * Symbolic resource IDs for the dlgAreaUDemo (dlgAreUDemo.rex and + * dlgAreaUDemoTwo.rex) programs. + */ + +#define IDC_ST_STATUS 111 +#define IDC_EDIT 112 +#define IDC_PB_0 113 +#define IDC_PB_1 114 +#define IDC_PB_2 115 +#define IDC_PB_3 116 +#define IDC_PB_4 117 +#define IDC_PB_5 118 +#define IDC_PB_6 119 Copied: ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemo.rex (from rev 8773, ooDialog/trunk/examples/dlgAreaUDemo.rex) =================================================================== --- ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemo.rex (rev 0) +++ ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemo.rex 2013-01-05 06:08:06 UTC (rev 8774) @@ -0,0 +1,100 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2006-2013 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ +/* DlgAreaDemo.Rex -- Demonstrate DlgArea & DlgAreaU Classes -- Feb 2006 */ + +.application~useGlobalConstDir("O", 'dlgAreaUDemo.h') + +MyDlg=.MyDialog~new +MyDlg~execute('ShowTop') + +return 0 + +::requires "ooDialog.cls" +/* ========================================================================= */ +::class MyDialog Subclass UserDialog +/* ========================================================================= */ +::method init +/* ------------------------------------------------------------------------- */ + forward class (super) continue + success=self~createCenter(250,250,'My Resizable Dialog',, + 'ThickFrame MinimizeBox MaximizeBox',,, + 'MS Sans Serif',8) + if \success then do + self~initCode = 1 + return + end + + self~connectResize('OnResize', .true) + +/* ------------------------------------------------------------------------- */ +::method defineDialog +/* ------------------------------------------------------------------------- */ +expose u + +u=.dlgAreaU~new(self) /* whole dlg */ +if u~lastError \= .nil then call errorDialog u~lastError + +u~noResizePut(IDC_PB_0) +e=.dlgArea~new(u~x , u~y , u~w('70%'), u~h('90%')) /* edit area */ +s=.dlgArea~new(u~x , u~y('90%'), u~w('70%'), u~hr ) /* status area */ +b=.dlgArea~new(u~x('70%'), u~y , u~wr , u~hr ) /* button area */ + +self~createEdit(IDC_EDIT, e~x, e~y, e~w, e~h, 'multiline', 'text') +self~createStaticText(IDC_ST_STATUS, s~x, s~y, s~w, s~h, , 'Status info appears here') + +self~createPushButton(IDC_PB_0, b~x, b~y('00%'), b~w, b~h('9%'), , 'Button' 0, 'Button'||0) +self~createPushButton(IDC_PB_1, b~x, b~y('10%'), b~w, b~h('9%'), , 'Button' 1, 'Button'||1) +self~createPushButton(IDC_PB_2, b~x, b~y('20%'), b~w, b~h('9%'), , 'Button' 2, 'Button'||2) +self~createPushButton(IDC_PB_3, b~x, b~y('30%'), b~w, b~h('9%'), , 'Button' 3, 'Button'||3) +self~createPushButton(IDC_PB_4, b~x, b~y('40%'), b~w, b~h('9%'), , 'Button' 4, 'Button'||4) +self~createPushButton(IDC_PB_5, b~x, b~y('50%'), b~w, b~h('9%'), , 'Button' 5, 'Button'||5) +self~createPushButton(IDC_PB_6, b~x, b~y('60%'), b~w, b~h('9%'), , 'Button' 6, 'Button'||6) +self~createPushButton(IDOK, b~x, b~y('90%'), b~w, b~h('9%'), 'DEFAULT', 'Ok') + +/* ------------------------------------------------------------------------- */ +::method onResize +/* ------------------------------------------------------------------------- */ +expose u +use arg dummy,sizeinfo +u~resize(self,sizeinfo) + +/* ------------------------------------------------------------------------- */ +::method unknown +/* ------------------------------------------------------------------------- */ +use arg msgname, args +if msgname~abbrev("BUTTON") then + self~newStatic(IDC_ST_STATUS)~setText('You Pressed Button' msgname~right(1)) Copied: ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemoThree.rex (from rev 8773, ooDialog/trunk/examples/dlgAreaUDemoThree.rex) =================================================================== --- ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemoThree.rex (rev 0) +++ ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemoThree.rex 2013-01-05 06:08:06 UTC (rev 8774) @@ -0,0 +1,281 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2006-2013 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * DlgAreaDemoThree.Rex + * + * Demonstrates a second approach to resizable dialogs. Essentially what this + * approach does is to defer the redrawing of the dialog controls until the + * user has finished resizing the dialog. + * + * This example is exactly like DlgAreaDemoTwo.rex, except it also demonstrates + * how to prevent the user from resizing the dialog smaller than a minimum + * size. Look at the connectResizing() method in init() and the onResizing() + * method for the code that does this. + * + * To better understand this example completely, please read the header + * comments in the DlgAreaDemoTwo.rex example. + */ + + .application~useGlobalConstDir("O", 'dlgAreaUDemo.h') + + dlg = .ResizableDialog~new + dlg~execute('ShowTop') + + return 0 + +::requires "ooDialog.cls" + +::class 'ResizableDialog' subclass UserDialog + +::method init + + forward class (super) continue + success = self~createCenter(250, 250, 'My Flicker Free Resizable Dialog', - + 'ThickFrame MinimizeBox MaximizeBox', , - + 'MS Sans Serif', 8) + if \ success then do + self~initCode = 1 + return + end + + self~connectResize('onResize', .true) + self~connectResizing('onResizing') + self~connectSizeMoveEnded('onSizeMoveEnded') + + +::method defineDialog + expose u sizing minMaximized + + u = .dlgAreaU~new(self) + if u~lastError \= .nil then call errorDialog u~lastError + + -- Tell the DialogAreaU object to not invoke the update method. + u~updateOnResize = .false + + -- We use these variables to track when to redraw, or not. + sizing = .false + minMaximized = .false + + u~noResizePut(IDC_PB_0) + e = .dlgArea~new(u~x , u~y , u~w('70%'), u~h('90%')) -- edit area + s = .dlgArea~new(u~x , u~y('90%'), u~w('70%'), u~hr ) -- status area + b = .dlgArea~new(u~x('70%'), u~y , u~wr , u~hr ) -- button area + + self~createEdit('IDC_EDIT', e~x, e~y, e~w, e~h, 'multiline') + self~createStaticText('IDC_ST_STATUS', s~x, s~y, s~w, s~h, , 'Status info appears here') + + self~createPushButton('IDC_PB_0', b~x, b~y('00%'), b~w, b~h('9%'), , 'Button' 0 , 'Button'||0) + self~createPushButton('IDC_PB_1', b~x, b~y('10%'), b~w, b~h('9%'), , 'Button' 1 , 'Button'||1) + self~createPushButton('IDC_PB_2', b~x, b~y('20%'), b~w, b~h('9%'), , 'Button' 2 , 'Button'||2) + self~createPushButton('IDC_PB_3', b~x, b~y('30%'), b~w, b~h('9%'), , 'Button' 3 , 'Button'||3) + self~createPushButton('IDC_PB_4', b~x, b~y('40%'), b~w, b~h('9%'), , 'Button' 4 , 'Button'||4) + self~createPushButton('IDC_PB_5', b~x, b~y('50%'), b~w, b~h('9%'), , 'Button' 5 , 'Button'||5) + self~createPushButton('IDC_PB_6', b~x, b~y('60%'), b~w, b~h('9%'), , 'Button' 6 , 'Button'||6) + self~createPushButton('IDOK', b~x, b~y('90%'), b~w, b~h('9%'), 'DEFAULT', 'Ok') + + +::method initDialog + expose minWidth minHeight + + -- The underlying edit controls internally resize themselves as the dialog + -- they are contained in is resized. We don't want that, so we disable that + -- behavior in the underlying edit control. + self~newEdit(IDC_EDIT)~disableInternalResize + + -- We will restrict the minimum width and minimum height to our original + -- width and height + minWidth = self~pixelCX + minHeight = self~pixelCY + + +-- The RESIZING event happens when the user is resizing the dialog, but *before* +-- the size of the dialog is actually changed. The first arg is a .RECT object +-- that describes the new size. If we change the coordinates in the rectangle, +-- and reply .true. The new size of the dialog will be our changed coordinates. +-- +-- Here, if the new size is smaller than we want, we just change the rectangle +-- coordinates to our minimum size. The 'direction' argument tells us which +-- edge of the dialog the user is dragging. We use that to decide which +-- coordinate(s) to change. +-- +-- A maximum size for the dialog could be enforced in a similar way. +::method onResizing unguarded + expose minWidth minHeight + use arg r, direction + + select + when direction == 'TOP' then do + if r~bottom - r~top < minHeight then do + r~top = r~bottom - minHeight + return .true + end + end + when direction == 'BOTTOM' then do + if r~bottom - r~top < minHeight then do + r~bottom = r~top + minHeight + return .true + end + end + when direction == 'LEFT' then do + if r~right - r~left < minWidth then do + r~left = r~right - minWidth + return .true + end + end + when direction == 'RIGHT' then do + if r~right - r~left < minWidth then do + r~right = r~left + minWidth + return .true + end + end + when direction == 'BOTTOMLEFT' then do + didChange = .false + + if r~bottom - r~top < minHeight then do + r~bottom = r~top + minHeight + didChange = .true + end + + if r~right - r~left < minWidth then do + r~left = r~right - minWidth + didChange = .true + end + + return didChange + end + when direction == 'BOTTOMRIGHT' then do + didChange = .false + + if r~bottom - r~top < minHeight then do + r~bottom = r~top + minHeight + didChange = .true + end + + if r~right - r~left < minWidth then do + r~right = r~left + minWidth + didChange = .true + end + + return didChange + end + when direction == 'TOPLEFT' then do + didChange = .false + + if r~bottom - r~top < minHeight then do + r~top = r~bottom - minHeight + didChange = .true + end + + if r~right - r~left < minWidth then do + r~left = r~right - minWidth + didChange = .true + end + + return didChange + end + when direction == 'TOPRIGHT' then do + didChange = .false + + if r~bottom - r~top < minHeight then do + r~top = r~bottom - minHeight + didChange = .true + end + + if r~right - r~left < minWidth then do + r~right = r~left + minWidth + didChange = .true + end + + return didChange + end + otherwise + nop + end + -- End select + return .false + +::method onResize unguarded + expose u sizing minMaximized lastSizeInfo + use arg sizingType, sizeinfo + + -- Save the size information so we know the final size of the dialog. + lastSizeInfo = sizeInfo + + -- The size / move ended event does not occur when the user maximizes, + -- minimizes, or restores from maximized / minimized. Because of that, we + -- need to redraw the client area under those conditions. + + if sizingType == self~SIZE_MAXIMIZED | sizingType == self~SIZE_MINIMIZED then do + minMaximized = .true + if sizingType == self~SIZE_MAXIMIZED then do + u~resize(self, sizeinfo) + self~redrawClient(.true) + end + end + else if sizingType == self~SIZE_RESTORED, minMaximized then do + minMaximized = .false + u~resize(self, sizeinfo) + self~redrawClient(.true) + end + else do + -- We are resizing now. + sizing = .true + end + + return 0 + + +::method onSizeMoveEnded unguarded + expose u sizing lastSizeInfo + + -- If we were resizing, force the dialog controls to redraw themselves. + if sizing then do + u~resize(self, lastSizeInfo) + self~redrawClient(.true) + end + + -- We are not resizing anymore. + sizing = .false + return 0 + + +::method unknown + use arg msgName, args + + if msgName~abbrev("BUTTON") then + self~newStatic(IDC_ST_STATUS)~setText('You Pressed Button' msgName~right(1)) Copied: ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemoTwo.rex (from rev 8773, ooDialog/trunk/examples/dlgAreaUDemoTwo.rex) =================================================================== --- ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemoTwo.rex (rev 0) +++ ooDialog/trunk/examples/resizableDialogs/DialogAreaU/dlgAreaUDemoTwo.rex 2013-01-05 06:08:06 UTC (rev 8774) @@ -0,0 +1,193 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2006-2013 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ... [truncated message content] |