/* GUIBEGIN STRING STRING1 List Item 1 List Item 2 List Item 3 List Item 4 DEND WINDOW , 52, 106, 400, 200, POPUP|CAPTION|SYSMENU|MINBOX|MAXBOX|THICK, , Drag List example FONT 8, 400, MS Shell Dlg LIST 3, 3, 94, 81, NOTIFY|BORDER|VSCROLL|TABSTOP, , MyList, , STRING1 DEND GUIEND */ /* This is an example of a "Drag List box". It allows the user to grab * one of the items in a listbox, and drag it to a new position. */ DO /* FUNCDEF some C structures that we'll have to convert * to a REXX Stem variable. */ FUNCDEF("DRAGLISTINFO", "32u, 32u, 32, 32") /* FUNCDEF some Windows APIs we need */ FUNCDEF("MakeDragList",", void", "comctl32") FUNCDEF("RegisterWindowMessage","32u, str","user32") FUNCDEF("LBItemFromPt","32, void, 32, 32, 32u", "comctl32") FUNCDEF("DrawInsert",", void, void, 32u", "comctl32") FUNCDEF("LoadStdCursor", "void, void, 32u", "user32", "LoadCursor") FUNCDEF("SetCursor", "void, void", "user32") CATCH FAILURE CONDITION('M') RETURN END /* Get a few standard mouse pointers we'll use */ CrossHairCursor = LoadStdCursor(, 32513) NoDropCursor = LoadStdCursor(, 32648) LIBRARY rexxgui GuiErr = "SYNTAX" GuiHeading = 1 GuiCreateWindow('NORMAL') Again: DO FOREVER GuiGetMsg() CATCH SYNTAX CONDITION('M') SIGNAL Again CATCH HALT FINALLY GuiDestroyWindow() END RETURN /* Called by Reginald after our main window, and all its * controls are created, but not yet shown. */ WM_INITDIALOG: /* Get the handle to our listbox */ handle = GuiInfo("HANDLE", "MyList") /* Call the Windows API MakeDragList to turn this into a * drag listbox */ MakeDragList(handle) /* Get the special message that Windows sends us when the user * drags an item in the listbox */ DragMessage = RegisterWindowMessage("commctrl_DragListMsg") /* Don't let Rexx Gui process this event. */ RETURN "" /* Called by Reginald when our main window receives a * message that REXX GUI doesn't know how to handle. * Such a message would be the "commctrl_DragListMsg" * message, whose message number we have stored in the * variable "DragMessage". */ WM_EXTRA: /* Is this a DragMessage for our listbox? */ IF ARG(3) = DragMessage THEN DO /* ARG(2) is a C structure that we have to convert * to a REXX stem variable. We use CONVERTDATA() to * do that, using one of the struct types we * FUNCDEF'ed. */ CONVERTDATA(ARG(2), "DRAGLISTINFO", "struct DRAGLISTINFO") /* dragListInfo.2 is now the handle * for the list box whose item is being dragged. * If we had several listboxes we set to be drag * lists, then we'd pass this handle to GuiInfo, * using a "VARIABLE" arg, to get the variable * name we associated with this listbox. But since * we have only 1 drag list in this example, we * know it's "MyList". */ /* Figure out which drag operation */ SELECT dragListInfo.1 /* Has the user just clicked on an item to drag it? */ WHEN 1157 /* DL_BEGINDRAG */ THEN DO /* Get the 0-based position of the item that is being dragged. This is * the original position of the item in the list. Save it in a variable * so we'll have it later when we process DL_DROPPED */ OldPosition = LBItemFromPt(dragListInfo.2, dragListInfo.3, dragListInfo.4) /* Display the drag mouse pointer */ DrawInsert(GuiWindow, ARG(1), 1) /* User hasn't yet dragged the item anywhere */ DragDrop = 0 /* Allow dragging to continue. Returning nothing aborts the drag operation, * so we can choose which items we allow to be dragged. */ RETURN 1 END /* Did the user start dragging the item? */ WHEN 1158 /* DL_DRAGGING */ THEN DO /* Get the 0-based position he has dragged the item to. NOTE: He hasn't * dropped it yet */ NewPosition = LBItemFromPt(dragListInfo.2, dragListInfo.3, dragListInfo.4) /* Make sure he draagged to a legal position */ IF NewPosition \= -1 THEN DO /* Display a crosshair mouse pointer to * let him know he can drio the item here */ SetCursor(CrossHairCursor) /* Allow if he drops here */ DragDrop = 1 END ELSE DO /* Display a "no drop" mouse pointer to let him know he can't drop here */ SetCursor(NoDropCursor) /* Ignore if he drops here */ DragDrop = 0 END END /* Did he drop the item? */ WHEN 1159 /* DL_DROPPED */ THEN DO /* Did he drag it to an allowable position? */ IF DragDrop == 1 THEN DO /* Yes. Get the final position where he dropped it */ NewPosition = LBItemFromPt(dragListInfo.2, dragListInfo.3, dragListInfo.4) /* Just make sure it's legal */ IF NewPosition \= -1 THEN DO /* NOTE: The drag list box doesn't reorder the items. We * need to do that. We have the original position of the * item (where 0 = first item), and its new position. * We need to delete at its old position, and insert at * the new position. There's one problem here. If the new * position is greater than the original position, then * after we delete, the new position will be off by one. * So let's check first and readjust */ /* Get the string at the original position */ GuiSendMsg("MyList", "GETLBTEXT", OldPosition + 1, "text") IF NewPosition > OldPosition THEN NewPosition = NewPosition - 1 /* Delete the original position */ GuiSendMsg("MyList", "DELETESTRING", OldPosition + 1) /* Insert at the new position */ GuiSendMsg("MyList", "INSERTSTRING", NewPosition + 1, text) END END END END /* Return 0 for DL_DRAG and DL_DROPPED */ RETURN 0 END /* Don't let Rexx Gui process this event. */ RETURN ""