/* GUIBEGIN WINDOW , 93, 157, 400, 200, POPUP|CAPTION|SYSMENU|MINBOX|MAXBOX|THICK, , Lasso Example FONT 8, 400, MS Shell Dlg ENTRY 24, 27, 101, 13, H_AUTO|BORDER|TABSTOP, , MyEdit1 RADIO 69, 70, 39, 10, AUTO|GROUP, , MyRadio1, , Radio LIST 141, 23, 48, 40, NOTIFY|BORDER|VSCROLL|TABSTOP, , MyList1 SLIDER 25, 89, 58, 13, , , MySlider1 DEND GUIEND */ /* * An example of handling the CTLCOLOREDIT event of a * REXX GUI window to set the color of ENTRY controls. * * In this example, we'll change the color of ENTRY controls in * window. This will be almost the same as colors.rex (which * handled the CTLCOLORSTATIC event) but here we're going to do * one other thing. Instead of changing the colors of all entry * boxes, we're going to change only one specific entry box. To * do this, you'll see how you can use the window handle arg to * our WM_CTLCOLOREDIT to determine the correct control. */ OPTIONS "C_CALL LABELCHECK WINFUNC NOSOURCE" LIBRARY rexxgui DO /* Register some Windows OS functions for our rubberband selection */ FUNCDEF("SetROP2", "32, void, 32u", "gdi32") FUNCDEF("GetDC", "void, void", "user32") FUNCDEF("ReleaseDC", "32, void, void", "user32") FUNCDEF("Rectangle", "32, void, 32, 32, 32, 32", "gdi32") FUNCDEF("SetCapture", "void, void", "user32") FUNCDEF("ReleaseCapture", "32,", "user32") /* Register some Windows OS functions for FindControlsWithinBox() */ RECT = "32,32,32,32" POINT = "32,32" FUNCDEF("GetWindowRect", "32, void, struct RECT stor", "user32") FUNCDEF("ScreenToClient", "32, void, struct POINT dual", "user32") FUNCDEF("IntersectRect", "32, struct RECT stor, struct RECT, struct RECT", "user32") CATCH FAILURE CONDITION("M") RETURN END GuiErr = "SYNTAX" GuiHeading = 1 GuiCreateWindow('NORMAL') /* Not yet doing the rubberband effect */ IsDragging = 0 Again: DO FOREVER GuiGetMsg() IF EXISTS('GuiObject') == 0 THEN DO IF EXISTS('GuiSignal') THEN DO END END CATCH SYNTAX CONDITION('M') SIGNAL Again CATCH HALT FINALLY GuiDestroyWindow() END RETURN /* ================== WM_LBUTTONDOWN ================== * This handles the LBUTTONDOWN message for my window. * * Reginald calls this when the user has clicked * the left mouse button. * * ARG(1) is a value that tells what keys (on the keyboard) * were held down while the mouse was moved. * ARG(2) is the X position of the mouse. * ARG(3) is the Y position of the mouse. * * NOTE: Since we SIGNAL here (from MyWindowProc), this is * not a real subroutine. Don't use PROCEDURE here. Instead, * use PROCEDURE on MyWindowProc if that's what you desire. */ WM_LBUTTONDOWN: /* Set the initial position and size of our selection box */ RubberBand.1 = ARG(2) RubberBand.2 = ARG(2) RubberBand.3 = ARG(3) RubberBand.4 = ARG(3) /* Draw initial rubberband selection box */ DrawSelectionBox(GuiWindow, RubberBand.) /* Capture the mouse */ SetCapture(GuiWindow) /* Indicate (to MouseMove() and MouseUp()) that we're * dragging our rubberband selection box */ IsDragging = 1 /* We handled the msg */ RETURN "" /* ================== WM_LBUTTONUP ================== * This handles the LBUTTONUP message for my window. * * Reginald calls this when the user has released * the left mouse button. * * ARG(1) is a value that tells what keys (on the keyboard) * were held down while the mouse was moved. * ARG(2) is the X position of the mouse. * ARG(3) is the Y position of the mouse. */ WM_LBUTTONUP: /* Are we dragging our selection box? */ IF IsDragging \= 1 THEN RETURN "" /* Erase the last selection box. Because we use mix * mode 7, by redrawing it a second time, that * effectively erases it without affecting the background */ DrawSelectionBox(GuiWindow, RubberBand.) /* We're done dragging, so clear the variable and release the mouse */ IsDragging = 0 ReleaseCapture() /* Adjust RubberBand. so that: * * RubberBand.1 = X position of the top left corner of the selection box * RubberBand.2 = Y position of the top left corner of the selection box * RubberBand.3 = X position of the bottom right corner of the selection box * RubberBand.4 = Y position of the bottom right corner of the selection box * * To figure out the width, you subtract RubberBand.1 from RubberBand.3 * To figure out the height, you subtract RubberBand.2 from RubberBand.4 */ temp = RubberBand.2 RubberBand.2 = RubberBand.3 RubberBand.3 = temp IF RubberBand.1 > RubberBand.3 THEN DO temp = RubberBand.3 RubberBand.3 = RubberBand.1 RubberBand.1 = temp END IF RubberBand.2 > RubberBand.4 THEN DO temp = RubberBand.4 RubberBand.4 = RubberBand.2 RubberBand.2 = temp END /* Let's just report the final position and size of the selection box */ GuiSay("Selected area:" || '0D0A'X || "X =" RubberBand.1 || '0D0A'X || "Y =" RubberBand.2 || '0D0A'X || "Width =" RubberBand.3 - RubberBand.1 || '0D0A'X || "Height =" RubberBand.4 - RubberBand.2) /* Now let's find out all of the REXX GUI controls that happen * to fall within the selection box area */ GuiInfo('CHILD', GuiWindow, 'FindControlsWithinBox') /* We handled the msg */ RETURN "" /* ================== WM_MOUSEMOVE ================== * This handles the MOUSEMOVE message for my window. * * Reginald calls this when the user has moved * the mouse pointer. * * ARG(1) is a value that tells what keys (on the keyboard) * were held down while the mouse was moved. * ARG(2) is the X position of the mouse. * ARG(3) is the Y position of the mouse. */ WM_MOUSEMOVE: /* Are we dragging our selection box? */ IF IsDragging = 1 THEN DO /* Erase the previous selection box. Because we use mix mode 7, by redrawing it * a second time, that effectively erases it without affecting the background */ DrawSelectionBox(GuiWindow, RubberBand.) /* Update RubberBand to have the new size for the selection box, * based upon where the mouse is now */ RubberBand.2 = ARG(2) RubberBand.4 = ARG(3) /* Now draw the new selection box */ DrawSelectionBox(GuiWindow, RubberBand.) END /* We handled the msg */ RETURN "" /* ================ DrawSelectionBox ================= * Draws our rubberband selection box based upon the * coordinates in the passed rect. variable. */ DrawSelectionBox: USE ARG window, rect. /* Get the Device Context (DC) for our window so we can call * the Rectangle() function to draw a rectangle in that window */ hdc = GetDC(window) /* SetROP2 sets the mix mode. The mix mode determines how certain other graphics functions * (such as Rectangle()) draw over the existing background of a window. Here we set it to * 7. * * The first arg is the Device Context. * * The second arg specifies the new mix mode. It can be one of the following values: * * 1 = Pixel is always 0. * 2 = Pixel is the inverse of mix mode 15's color. * 3 = Pixel is a combination of the colors common to both the screen and the inverse of the pen. * 4 = Pixel is the inverse of the pen color. * 5 = Pixel is a combination of the colors common to both the pen and the inverse of the screen. * 6 = Pixel is the inverse of the screen color. * 7 = Pixel is a combination of the colors in the pen and in the screen, but not in both. * 8 = Pixel is the inverse of mix mode 9's color. * 9 = Pixel is a combination of the colors common to both the pen and the screen. * 10 = Pixel is the inverse of mix mode's 7 color. * 11 = Pixel remains unchanged. * 12 = Pixel is a combination of the screen color and the inverse of the pen color. * 13 = Pixel is the pen color. * 14 = Pixel is a combination of the pen color and the inverse of the screen color. * 15 = Pixel is a combination of the pen color and the screen color. * 16 = Pixel is always 1. * * If SetROP2 succeeds, the return value is the previous mix mode. If * SetROP2 fails, the return value is zero. */ SetROP2(hdc, 7) /* Draw our selection box in our window */ Rectangle(hdc, rect.1, rect.3, rect.2, rect.4) /* We're done with the DC now */ ReleaseDC(window, hdc) RETURN /* =============== FindControlsWithinBox =================== * Figures out what REXX GUI controls are within the * selection box area. * * Note: If you use PROCEDURE here, you must EXPOSE the * "RubberBand." and "GuiWindow" variables. */ FindControlsWithinBox: /* Get the next control's handle. */ child = ARG(1) /* Get the position and size of this control (relative to the desktop). */ GetWindowRect(child, childRect) /* Readjust its position within our window */ ScreenToClient(GuiWindow, childRect) temp.1 = childRect.3 temp.2 = childRect.4 ScreenToClient(GuiWindow, temp) childRect.3 = temp.1 childRect.4 = temp.2 /* Now see if it is within our select box area. */ IF IntersectRect(temp, RubberBand, childRect) == 1 THEN GuiSay("Control" ARG(2) "is within the selection box.") /* Return 1 to continue enumerating controls, or 0 to stop. */ RETURN 1 /* If you want to restrict the match to only those controls that have an associated REXX variable, you should instead do the following: FindControlsWithinBox: /* Is this a control that has an associated variable? If so, then * ARG(2) is that variable name. */ IF ARG(2) \== "" THEN DO /* Get the position and size of this control within our window. */ GetCtlPlacement(ARG(2), "childRect.1", "childRect.2", "width", "height") childRect.3 = childRect.1 + width childRect.4 = childRect.2 + height /* Now see if it is within our select box area. */ IF IntersectRect(temp, RubberBand, childRect) == 1 THEN GuiSay("Control" ARG(2) "is within the selection box.") END /* Return 1 to continue enumerating controls, or 0 to stop. */ RETURN 1 */