Is it possible to define on which screen a window appears?
I tried to find a solution, but all the time get only info about how to put somthing on screen or how to monitor a database.
Assuming this is classic ABL GUI.
The Window's position on the screen is determined by the X and Y attribute of the window. That is in pixel relative to the top/left corner of the "primary" screen.
You need to go to X < 0 (negative) if your default screen is the right one and you want to address the left monitor.
You can use the .NET System.Windows.Forms.Screens:AllScreens array to get details about the available monitors and their size and relative desktop positions:
DEFINE VARIABLE oScreens AS System.Windows.Forms.Screen NO-UNDO EXTENT .
DEFINE VARIABLE iCount AS INTEGER NO-UNDO.
DEFINE VARIABLE i AS INTEGER NO-UNDO.
/* Gets an array of all the screens connected to the system. */
ASSIGN oScreens = System.Windows.Forms.Screen:AllScreens
iCount = EXTENT(oScreens) .
DO i = 1 TO iCount :
MESSAGE "screen" i SKIP
"Width" oScreens[i]:Bounds:WIDTH SKIP
"Height" oScreens[i]:Bounds:HEIGHT SKIP
"X" oScreens[i]:Bounds:X SKIP
"Y" oScreens[i]:Bounds:Y SKIP
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.
DEFAULT-WINDOW:VISIBLE = TRUE .
DEFAULT-WINDOW:X = -1000 .
MESSAGE DEFAULT-WINDOW:X DEFAULT-WINDOW:Y .
For instance my left screen (center is primary) is 2560x1440 and starts with X = -2560.
So to have a window on it's top left corner, I set X to -2560 and Y to 0.
Related
I am new to progress 4GL. In my program, I tried to create a form using progress 4GL. The form has two fields one is DB name and another one is DB Description. The scope of this form is by default this should have one DB name and description and if a user-entered or keep blank in the field of DB name then an alert box should give a message. I have developed the form but when I run it the program keeps continuously running and window form goes not responding stage. I don't get a chance to enter or keep blank to the DB field name. Let me share my code and please help to find out what is the issue and why it's continuously running.
define variable cArcDB as character no-undo format "x(20)" INIT "qadb".
define variable cArcDBDesc as character no-undo format "x(25)" INIT "archive database".
define variable cTmp as character NO-UNDO.
form
cArcDB colon 25
cArcDBDesc colon 25
with frame frArchiveDB width 80 side-labels.
MAIN-LOOP:
REPEAT:
display
cArcDB
cArcDBDesc
with frame frArchiveDB.
set
cArcDB
with frame frArchiveDB editing:
if frame-field = "cArcDB" then do:
/* Find next/prev record from ttAppDB */
cTmp = cArcDB:input-value in frame frArchiveDB.
display
cArcDB
cArcDBDesc
with frame frArchiveDB.
end.
end. /* editing */
cArcDB = trim(cArcDB).
if cArcDB = "" then do:
/* Blank not allowed */
/* {us/bbi/pxmsg.i &MSGNUM=40 &ERRORLEVEL=3} */
next-prompt cArcDB with frame frArchiveDB.
undo MAIN-LOOP,retry MAIN-LOOP.
end.
END.
Please have look at the online reference of the "EDITING phrase". To me it looks like you're missing the READKEY after the beginning of the EDITING block and you also need to "APPLY LASTKEY" at some point. See the sample there:
/* Update Customer fields, monitoring each keystroke during the UPDATE */
UPDATE Customer.Name Customer.Address Customer.City Customer.State SKIP
Customer.SalesRep HELP "Use the space bar to select a SalesRep"
WITH 2 COLUMNS EDITING: /* Read a keystroke */
READKEY.
/* If the cursor is in any field except SalesRep, execute the last key
pressed and go on to the next iteration of this EDITING phrase to check
the next key */
IF FRAME-FIELD <> "SalesRep" THEN DO:
APPLY LASTKEY.
IF GO-PENDING THEN LEAVE.
ELSE NEXT.
END.
/* When in the SalesRep field, if the last key pressed was the space bar
then cycle through the sales reps */
IF LASTKEY = KEYCODE(" ") THEN DO:
FIND NEXT SalesRep NO-ERROR.
IF NOT AVAILABLE SalesRep THEN FIND FIRST SalesRep.
DISPLAY SalesRep.SalesRep # Customer.SalesRep.
NEXT.
END.
/* If the user presses any one of a set of keys while in the SalesRep field,
immediately execute that key */
IF LOOKUP(KEYFUNCTION(LASTKEY),
"TAB,BACK-TAB,GO,RETURN,END-ERROR") > 0 THEN APPLY LASTKEY.
ELSE BELL.
END.
Hello Progress Experts!!!
I am trying to display the different colors based on percentage completion in progress bar like
percentage 0% - 25% - Red , 25% - 50% - Yellow , 50% - 100% - Green Color.
The concern here is the following codes helps to provide percentage completion in FILL-IN box but I don't know how to give colors.
Note - Color should change and move gradually in FILL-IN box.
(like we usually see progress bar in the system while copy and paste into another folder).
I heard we can use .NET methods in progress. It would be better if possible using this.
This might be stupid question(move gradually ) or unviable in progress. Yeah! as you know keep asking question why or why not is good for get some knowledge.
Please throw a small lamp here which gives bright to the dark.
DEFINE VARIABLE I AS INTEGER NO-UNDO.
DEFINE VARIABLE iPercentage AS INTEGER NO-UNDO.
DEFINE VARIABLE iComp AS INTEGER NO-UNDO.
DEFINE VARIABLE iRec AS INTEGER NO-UNDO.
ASSIGN
I = 0
iComp = 0
iRec = 0
iPercentage = 0.
/* Calculating Total records*/
FOR EACH <table> NO-LOCK:
iRec = iRec + 1.
END.
/* Taking each records from the same table to update*/
FOR EACH <table> NO-LOCK:
I = I + 1.
IF I = 1 THEN DO:
RUN UpdateRecord.p (INPUT <table>.<tablefield>)
ASSIGN
iComp = iComp + I.
iPercentage = 100 * (iComp / iRec).
DO WITH FRAME {&FRAME-NAME}:
ASSIGN
/* fiProgress is FILL-IN */
fiProgress:SCREEN-VALUE = STRING(iPercentage) + '%'.
PROCESS EVENTS.
END.
IF iPercentage = 100 THEN DO:
MESSAGE "Record Updation Is completed".
END.
ELSE DO:
I = 0
NEXT.
END.
END.
END.
(...) color should change and move gradually (...)
If by gradually you would like a real gradient effect, you're out of luck using pure Progress. BGCOLOR only accepts the colors defined in the palette (1-15, unless you want to create your own dynamic new colors (which is possible, but would require some work).
You can, however, assign it to an ActiveX field (formerly known as OCX) using the RGB-VALUE function, but if you're going down that route, I bet you can probably find an ActiveX progress bar to use and eliminate the need to recreate the wheel. I'll take your question as a pure progress feature you'd like to add.
For the sake of code reusability and adaptation, which is the goal of this site, I decided to create something that can be independent from your posted code (if you'll allow me), but easily built into it.
So in this example you should have 2 fill-ins, one of them with NO-LABEL and on top of the first, at the exact same column and row coordinates.
DEFINE VARIABLE iCount AS INTEGER NO-UNDO.
DEFINE VARIABLE iCalc AS INTEGER NO-UNDO.
REPEAT:
ASSIGN fill-in-1:BGCOLOR = IF iCount = 0 THEN 12
ELSE IF iCount = 25 THEN 14
ELSE IF iCount = 50 THEN 2
ELSE IF iCount = 75 THEN 10
ELSE fill-in-1:BGCOLOR.
ASSIGN iCount = iCount + 1.
/* Calculate reduction and placement of white fill-in */
ASSIGN iCalc = INT((100 - iCount) * fill-in-1:WIDTH / 100)
fill-in-2:WIDTH = if iCalc <> 0 then iCalc else 0.1
fill-in-2:COLUMN = fill-in-1:COLUMN + (fill-in-1:WIDTH - iCalc).
IF iCalc = 0 THEN
ASSIGN fill-in-2:VISIBLE = NO.
/* /End calculation */
ASSIGN fill-in-1:SCREEN-VALUE = STRING(iCount).
IF iCount = 100 THEN LEAVE.
PAUSE 0.2 NO-MESSAGE.
PROCESS EVENTS.
END.
This snippet works by itself sleeping for 0.2 seconds so you can get the idea of what's going on. Remove the pause and replace iCount with your percentage and you should get what you are looking for. PROCESS EVENTS would be a good idea, but not necessary to have.
Hope this helps.
EDIT: Shout out to my buddy Marlon Berkenbrock #marlonberkenbrock for bringing to my attention he got a zero width warning (which never showed to me due to my session configurations). The current version fixes that.
You may be able to achieve this with fiProgress:BGCOLOR but color values in ABL GUI are pretty limited as they are limited to the color palate loaded at session start. You can, technically, overwrite them at runtime, but it's not a great idea.
I found some other way for my question and could see bar moving gradually.
Thanks #bupereire for an idea.
Note - FILL-IN box width should be 1.00
DEFINE VARIABLE iCount AS INTEGER NO-UNDO.
DEFINE VARIABLE iCalc AS INTEGER NO-UNDO.
DO WITH FRAME {&FRAME-NAME}:
REPEAT:
ASSIGN iCount = iCount + 1
iCalc = INT(100 - iCount)
fill-in-1:WIDTH = 1
fill-in-1:WIDTH = (fill-in-1:WIDTH + iCount)
fill-in-1:BGCOLOR = IF iCount < 25 THEN 4
ELSE IF (iCount > 25 AND iCount < 50) THEN 9
ELSE IF (iCount > 50 AND iCount < 75) THEN 14
ELSE IF (iCount > 75 AND iCount < 100) THEN 10
ELSE fill-in-1:BGCOLOR.
IF iCount = 100 THEN LEAVE.
PAUSE 0.5 NO-MESSAGE.
PROCESS EVENTS.
END.
END.
END PROCEDURE.
The UI is as following:
The tool "AutoIt Window Info" can only locate the elements in red (red rectangle area), the sub items can not be located.
So how can I expand or operate these items?
Usually Windows controls can be accessed using keystrokes as well.
In the screen-dump the Farmtt element is selected. That would be your starting point.
You may try:
Send("{DOWN}") Move down an element.
Send("{TAB}") Navigate to next control (button, checkbox, etc)
Send("{NumPadMult}") Recursively expands folders in a SysTreeView32.
Send("{ENTER}") ENTER key on the main keyboard
etc.
Reference:
https://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm
There are two things over here:
1) Use the following code snippet:
;Gets the handle for the text
Func readFirstlevelTreeNodes($hWndCtrl)
Local $firstItemHandle = _GUICtrlTreeView_GetFirstItem ($hWndCtrl)
Local $iCount = _GUICtrlTreeView_GetSiblingCount( $hWndCtrl, $firstItemHandle )
Dim $aRet[$iCount]
$aRet[0] = $firstItemHandle
For $index = 1 To $iCount - 1
$aRet[$index] = _GUICtrlTreeView_GetNextSibling ( $hWndCtrl, $firstItemHandle )
$firstItemHandle = $aRet[$index]
Next
getTreeNodeTextList($hWndCtrl,$aRet)
EndFunc
; Gets the text for given sibling node handle lists
Func getTreeNodeTextList($hWndCtrl,$aRet)
ConsoleWrite("Tree Node first level list"&#CRLF)
For $index = 0 To Ubound($aRet) -1
ConsoleWrite(_GUICtrlTreeView_GetText ( $hWndCtrl, $aRet[$index] )&#CRLF)
Next
EndFunc
You may see the output for the first level tree nodes.
2) If you still dont see the output then please verify the control handle values and window handles. If they are correct and it still doesnt show the first level tree nodes then try running your sciTE editor as administrator.
I think this should help.
I want to use space bar to "click" a specific button in a window with autoit (without focusing the program?), like a "start" button in a game.
I tried to use ControlClick function but It's doing nothing by the way. I think i'm doing something wrong.
HotKeySet( "{space}", "MyFunction")
Func MyFunction()
ControlClick ( "title", "text", controlID [, button = "left" [, clicks = 1 [, x [, y]]]] )
EndFunc
Is it something like that?
Your way doing it is good. You are missing the title and the controlID of the ControlClick function. The 1st and 3rd parameter should be set to the title of the window and the control ID of the control.
To get those use the AutoIt tool that comes with autoit installation.
Set those properly and the code should work.
U can use it like this.
First start AutoIt info program to get desired coordinates ( place where u want to click ), use finder tool to get coorinates of mouse and edit it in a script.
So when u run ur script it will do nothing untill u press Spacebar, then it will run function MyFunction 1 time.
So it move mouse on given position, make pause of half second then left click on desired position $x and $y 1 time and srcipt stop untill u press space again then he make same procedure.
I added exit function so u can turn it off by just press ESC key.
HotKeySet( "{SPACE}", "MyFunction")
HotKeySet( "{ESC}", "CloseScript")
Global $x = 519 ; x is first value of mouse position
Global $y = 900 ; y is second value of mouse position
While 1
sleep(10)
Wend
Func MyFunction()
MouseMove($x, $y, 2) ; moves the mouse pointer do mouse position with speed 2
Sleep(500) ; wait 500 ms half of second ( delay )
MouseClick("left", $x, $y, 1, 2) ; now click left mouse key on mouse position, 1 click with speed 2
EndFunc
Func CloseScript()
Exit
EndFunc
I'm looking to generate placeholders and variables that can change depending on configured proportions such as the following:
$small-margin-top
$large-margin-top
$small-padding-bottom
Where each placeholder applies the corresponding, generated variable to the rule:
$small-margin-top
margin-top $marginsmall
$large-margin-top
margin-top $marginLarge
$small-padding-bottom
margin-bottom $marginSmall
I have statically defined the variables for now:
/* Margin */
$margin = 1rem
$marginsmall = $margin / $multiplier
$marginlarge = $margin * $multiplierLarge
$marginmini = $marginSmall / $multiplierLarge
But I get an error:
TypeError: expected "name" to be a string, but got ident:marginmini
properties = margin padding
proportions = mini small medium large
directions = top left bottom right
for property in properties
for proportion in proportions
for direction in directions
${property}-{direction}-{proportion}
{property}-{direction} lookup(property + proportion)
How can I generate placeholders for my proportions variable, such that the generated placeholders may be extended later (#extend $margin-large)?
EDIT: here is the working solution
The lookup bif accepts a string, and you are passing an ident (margin, padding, etc. without quotes). You can convert them to string by using concatenation. Also, you miss a $ sign:
properties = margin padding
proportions = mini small medium large
directions = top left bottom right
for property in properties
for proportion in proportions
for direction in directions
${proportion}-{property}-{direction}
{property}-{direction} lookup('$' + property + proportion)