VB.NET is seeing the wrong monitor as having the TaskBar for computing the height - vb.net

When I run this VB.NET code in my WinForms program it displays the expected results if Monitor #1 is on the left, and Monitor #2 is on the right.
(And Monitor #1 contains the Windows TaskBar.)
But if the user has his monitors switched around, with Monitor #2 on the left (containing the TaskBar), and #1 on the right... the height is now wrong.
My code then (incorrectly) assumes the Monitor with the TaskBar has a LARGER value for the height.
Is there a way to fix that? (Without forcing 1000s of users to switch their Monitors around... or switch the TaskBars to the other monitor.)
Or am I totally misunderstanding "WorkingArea()"????
Dim msg As String = ""
Dim numberOfMonitors As Int16 = Screen.AllScreens.GetUpperBound(0) + 1
If (numberOfMonitors >= 1) Then msg &= "Monitor #1 = " & Screen.AllScreens(0).WorkingArea.Width & " x " & Screen.AllScreens(0).WorkingArea().Height & ". "
If (numberOfMonitors >= 2) Then msg &= "Monitor #2 = " & Screen.AllScreens(1).WorkingArea.Width & " x " & Screen.AllScreens(1).WorkingArea().Height & ". "
Call MsgBox(msg)

No you are not misunderstanding Working area. Here is the definition from MSDN
The working area is the desktop area of the display, excluding taskbars, docked windows, and docked tool bars.
WorkingArea will return the entire area of the screen if the Windows Taskbar is set to Auto-Hide, no matter whether the Taskbar is currently displayed or not.
I would look into two propertys of the Screen class one is Primary which returns a Boolean value indicating wether or not that screen is the Primary, the second is just use the PrimaryScreen Property to get the Working area of your Primary Screen.
Caveat: I do not have a dual monitor system powered up at this time to verify if this works.

Related

Word VBA: Static Status dialog window

I've created a form that works well with macros running in the background to validate data and then print the document to a specific printer on the network.
The key element of this process is a production number value which I would like to keep a running log of and display in a static status dialog window. In other words, a popup window similar to a MsgBox that would not interfere with other actions on the form, but float on top of the document.
Visual concept of this would be...
User could shift the window away from their work if needed. Close the window if they desired, but pragmatically I want to re-pop/refresh the data in the window each time the background macro completes.
I can't use MsgBox, because it forces a closure of the window before the user can continue working on the document. I just want this visible to the user so they know what was last worked on and the few prior to that.
Any idea what control I might be able to use, or switch to MsgBox that would allow the user to continue working?
Ken...
PS: I found this and am trying to find a way to make this work for me. So far I have managed to get to function in the manner I want, but the lingering issue is how to call this PS script and include the information I need to display.
Alternatives to MsgBox in VBScript - StackOverflow
PPS: I opted to go a slightly different route and release the form with a MsgBox that is displayed at the end of the macro. I describe this in the solution noted below.
Instead of using a MsgBox, please consider using a VBA Userform. They're not much more complicated to use than a MegBox, but you can set them to be Modeless. Modeless dialogs remain open on-screen while you work on the Word document. Here'is Microsoft's page on setting dialogs as Modal or Modeless: Show method
If you search on VBA modeless dialog, you'll find many other helpful pages on the subject.
After doing much research, I've come back to revising my macro to incorporate static variables and a MsgBox at the end to report the last 5 production numbers that have been printed.
To provide a means of bringing up this MsgBox for reference, between printing runs, I created an OnlyNum variable as string and replaced the MsgBox I had for letting the users know they were only to use numbers in this field with that message. The end of that trap diverted the flow to the bottom of the macro (where the MsgBox that displayed the last five print jobs has been placed).
So, when the status MsgBox is displayed as a result of printing it only shows the last five events. If the trap captures it, it shows the message letting the user know to only use numerals and then displays the last five events.
Code reference:
Private Sub CommandButton1_Click()
Dim Prod As String
Dim Temp As String
Dim OnlyNum As String
Static ProdNum1 As String
Static ProdNum2 As String
Static ProdNum3 As String
Static ProdNum4 As String
Static ProdNum5 As String
'Check for only numeric value of TextBox1.Text
If Not IsNumeric(TextBox1.Value) Then
OnlyNum = "only numbers allowed" & vbCrLf & vbCrLf
Cancel = True
GoTo NotToday
End If
'Remove any spaces from TextBox1.Text
Prod = Replace(TextBox1.Text, " ", "")
'If the resulting lenght is equal to 7 Print it.
If Len(Prod) = 7 Then
ActiveDocument.PrintOut
'Update recent production numbers (5 in total)
ProdNum5 = ProdNum4
ProdNum4 = ProdNum3
ProdNum3 = ProdNum2
ProdNum2 = ProdNum1
ProdNum1 = Prod & " - " & Now() ' Insert a new production number with timestamp
TextBox1.Text = "" 'Clear the value of TextBox1.Text to prepare for the next Production number
Else
MsgBox ("Production Numbers must be 7 digits and contain only numerials.")
End If
NotToday:
Application.ActivePrinter = Temp
MsgBox (OnlyNum & ProdNum1 & vbCrLf & ProdNum2 & vbCrLf & ProdNum3 & vbCrLf & ProdNum4 & vbCrLf & ProdNum5)
OnlyNum = "" 'Reset value of OnlyNum
End Sub

Running a report directly and from a navigation form - reference issue

I have a form in MS Access (365) which accepts various selection criteria and runs a report with those criteria built into the wherecondition of a DoCmd.OpenReport command. The report is run via a button with On Click VBA code, since the wherecondition has to be built according to which, if any, criteria have been chosen. That all works fine when I open the selection criteria form directly. I want to open the selection criteria form via a navigation form, since there will be other, similar reports with selection criteria that I want to run from within the same navigation form.
As stated above, everything works when I open the selection criteria form directly and run the report but when I tried it via a navigation form, it didn't work. That's ok, I found a solution on the MS Dev Center site which works when I run the selection criteria form (and then the report) from the navigation form. All fine. But then (of course) the references within the button On Click code don't work when I open the selection criteria form directly and run the report. I would like to be able to run the selection criteria form and then the report from both positions - directly from MS Access and via the navigation form. There will presumably be some way to achieve this but (as I said above, I am new to MS Access and VBA) I could spend a lot of time clutching at shadows. Hopefully, someone will be able to tell me the simplest way to do this?
Code sample with relevant comments below. On runnning the selection criteria form and report directly, the line commented as AAA works ok, MsgBox ABB and DDD and those beyond all show; on running them via the navigation form, line BBB works ok, MsgBox ABB and DDD and those beyond all show (well, they would except that I haven't yet coded the [NavigationSubform] option into all the other whereconditon building stuff). When I switch the lines AAA and BBB (ie, comment the other one out) MsgBox AAA show ok, then it fails with:
Can't find referenced form "frmSelectSpeciesSiteDates"
before reaching MsgBox DDD.
MsgBox "ABB"
'If Not Forms![frmSelectSpeciesSiteDates]![cboCommonName] = "" Then
' AAA Works when frmSelectSpeciesSiteDates is run directly
If Not Forms![frmNavSelectiveReports]![NavigationSubform].[Form]![cboCommonName] = "" Then
' BBB Works when frmSelectSpeciesSiteDates is called from a navigation form
strWhereCondition = strWhereCondition & "[common name] = " & Chr(34) & Me![cboCommonName] & Chr(34)
End If
MsgBox "DDD"
You have a form named frmSelectSpeciesSiteDates which has a combobox named cboCommonName. The form also includes VBA code which uses the combobox value to modify a string variable ...
strWhereCondition = strWhereCondition & "[common name] = " & Chr(34) & Me![cboCommonName] & Chr(34)
However you only want to modify the string when the combobox contains something other than an empty string. And that is where you're struggling. You reference the combobox one way when the form is opened directly as a top-level form, and another way when it is contained in a navigation form ...
Forms![frmSelectSpeciesSiteDates]![cboCommonName]
Forms![frmNavSelectiveReports]![NavigationSubform].[Form]![cboCommonName]
I suggest you abandon both of those and refer to the combobox the same as where you modify the string (Me!cboCommonName) ...
If Not Me!cboCommonName = "" Then
strWhereCondition = strWhereCondition & "[common name] = " & Chr(34) & Me!cboCommonName & Chr(34)
End If

Multiple instances of a predesigned form in VB

Visual Studio 2010,
Visual Basic .NET
I have a form (frmImages) that opens when an image is clicked on inside a WebBrowser (wbContent) contorl on a form (frmContent).
I want the user to be able to click multiple images and open multiple instances of frmImages.
UPDATE
Here is what I am working with now, am I heading in the right direction?
This gives me the ability to open multiple instances but opens a duplicate. So for every image I click on, two identical forms open.
Dim images As New frmImages
If engineLine.IndexOf("\") <> -1 Then
images.wbImages.Navigate(New Uri(engineLine & holdHTML))
Else
images.wbImages.Navigate(New Uri(filePath & "IETMS\" & engineLine & "\" & engineLine & holdHTML))
End If
images.Text = ietmSelect & " - " & workPacket & " - " & removeTitleLinks(figTitle)
images.Show()
You just need to create another instance of the form (NEW). Of coarse, your form cannot be modal or else they will never be able to access the parent form to click another image.
Dim x as new frmImages
x.show
x = new frmImages
x.show
Create all your form instances explicitly, especially when you want more than one instance of a form. In your example, you are creating one explicitly (frmImages2), but also using the VB default instance. VB allows you to use the name of the form class as a default instance, but this is a bad practice (and a bad feature - but VB is designed around making it easier for very junior programmers even if it makes it more confusing for all the rest).

Capturing screenshot while workstation is locked

I would like to capture a screenshot of the monitor or a window, preferably using AutoIt (I am open to using any convenient method). The method needs to be able to function while the workstation is locked, due to the program being run overnight.
I cannot simply put code to unlock the workstation, as it poses a security risk. Current behavior: _ScreenCapture_SaveImage() saves a blank screen with only the mouse showing.
Try using captdll.dll to capture fullscreen or a program window.
$LogFilePath = "C:\Temp"
$TimeStamp = #YEAR & #MON & #MDAY & #HOUR & #MIN & #SEC
; Capture full screen
; Fist parameter - filename, last - jpeg quality.
$erg = DllCall("captdll.dll", "int:cdecl", "CaptureScreen", "str", $LogFilePath & "\Ce2eC_" & $TimeStamp & ".JPG", "int", 75)

Attachmate receive host string and react with conditional response using VBA

Using Attachmate, I am trying to write a VBA script that reacts when a specific phrase occurs and automatically executes commands via inline commands. Essentially, when a phrase appears, an inputbox appears asking the user for a specific quantity and the VBA code takes that quantity, inserts it into the terminal and then jumps around different menus to create an internal label. However, my problem is that I don't know how to have the VBA code react to the different strings that may be returned by the host. Sometimes it says "enter to continue" and sometimes it says "select user". So what I want it to do is based on the statement it receives to do a certain action, but I don't know what the command is for capturing what the terminal is receiving from the host. I've tried "waitforstring" and "readline" but it is obvious I am not using them correctly. Below is the code I have built thus far, please be gentle as it is still very unfinished. I have commented out several parts of it in attempts to troubleshoot my problems:
'variable declarations
Dim count As Long 'var used to indicate how many times code should loop (how many labels should be print)
Dim drugname As String
Dim qtyinput As Long
Dim CR As String ' Chr(rcCR) = Chr(13) = Control-M
Dim LF As String ' Chr(rcLF) = Chr(10) = Control-J
Dim strcheck As String
'assign values to variables
count = 0
CR = Chr(Reflection2.ControlCodes.rcCR)
LF = Chr(Reflection2.ControlCodes.rcLF)
qtyinput = InputBox("Number of items being sent", Quantity)
drugname = .GetText(22, 15, 22, 46) ' StartRow:=22, StartColumn:=15,EndRow:=22, EndColumn:=46 'copies text from screen
' Press EditCopy (Copy the selection and put it on the Clipboard).
'.Copy rcSelection, rcAsPlainText -- not needed
.Transmit qtyinput & CR
.Transmit CR
'strcheck = .readline("00:00:01")
'MsgBox strcheck
'If .WaitForString("Press " & Chr(34) & "RETURN" & Chr(34) & " to continue, " & Chr(34) & "^" & Chr(34) & " to stop: ") Then .Transmit CR
'Select Case strcheck
' Case strcheck Like "to continue"
' .Transmit CR
'Case strcheck Like "*Select CLIENT*"
' .Transmit CR
'End Select
.Transmit "^MED" & CR
.Transmit "3" & CR
.Transmit "10" & CR
First of all, Attachmate is the company, and they have a few products for accessing Mainframe sessions from Windows including EXTRA! and Reflections, both of which share a common scripting language, which is nice and easy to use from within VBA.
However, EXTRA! tends to have fewer commands available to use than Reflections, which is the more expensive product, so you have to get a little creative with your VBA.
I think you are using EXTRA!, so the command you are looking for is "GetString"
I use VBA to interact with a mainframe session in EXTRA!, and I know that my mainframe command is successful when three stars appear on the screen in a certain position.
The mainframe command can take anywhere between 1 second and 5 minutes to complete, so I use "GetString" to poll the mainframe session every second, waiting for the three stars before I continue:
Do Until Sess0.Screen.GetString(14, 2, 3) = "***"
Application.Wait (Now + TimeValue("0:00:01"))
Loop
The syntax for "GetString" is: GetString(Row, Column, Length)
In my case the stars appear at row 14, column 2, and I know there will always be 3 of them, so I set my string length to 3.