Is there a way in visio to show/hide a shape when clicking on another shape in Presentation Mode? - visio

I am trying to do a very basic user interface wireframe using Visio 2016. I want to do things like show a dialog box when I click on a button and then hide that dialog box when I click on the "ok" in the dialog. I've been previously doing this by completely copying the entire page and adding what I want to the new page and using the "Hyperlink" option. It would be a lot easier if there were a way to show or hide a shape when I click on another shape. Is there any capability like that?

In Presentation Mode? No. There is almost no interaction available in Presentation Mode.

You can get some code to run in fullscreen mode. I've hooked the application MouseMove event in the sample below. It makes the outline of the shape you are over fatter while the mouse is over that shape.
You can test the code by drawing a bunch of rectangles on a page, then moving the mouse in fullscreen mode.
I wasn't able to trap MouseDown in fullscreen mode, though.
More notes in the code's comments!
Option Explicit
'// Notes:
'//
'// - This code works in full screen mode!
'// - The mouse-up code doesn't work if you drag the shape,
'// (which won't be an issue in full-screen mode!)
Dim WithEvents m_visApp As Visio.Application
Private m_visShpMouseDown As Visio.Shape
Private m_lineWeightFormulaU As String
Private Sub Document_RunModeEntered(ByVal doc As IVDocument)
'// Toggle RunMode on and off via the blue triangle button just
'// right of the Stop/Reset button. This lets you reset the
'// code without closing and opening the file every time! Also,
'// this proc runs when you open the file, so m_visApp will
'// be set up to receive events!
Set m_visApp = Visio.Application
End Sub
Private Sub m_visApp_MouseMove(ByVal Button As Long, ByVal KeyButtonState As Long, ByVal x As Double, ByVal y As Double, CancelDefault As Boolean)
Dim pg As Visio.Page
Set pg = m_visApp.ActivePage
If (pg Is Nothing) Then GoTo Cleanup
Dim shp As Visio.Shape
For Each shp In pg.Shapes
If (shp.HitTest(x, y, 0)) Then
'// The mouse is over a shape.
If (shp Is m_visShpMouseDown) Then
Debug.Print "MouseMove over same shape! " & DateTime.Now
GoTo Cleanup
Else
Debug.Print "MouseMove over shape! " & DateTime.Now
'// Restore any previously mouse-overed shape:
Call m_restoreShape
'// Save the original lineweight and change it to
'// something thicker:
m_lineWeightFormulaU = shp.CellsU("LineWeight").FormulaU
Set m_visShpMouseDown = shp
'// Make the lineweight thick:
shp.CellsU("LineWeight").FormulaForceU = "5pt"
GoTo Cleanup
'// Note: the above won't change the lineweights
'// for all shapes in a group. If you intend to use
'// this on grouped shapes, you'll have to recurse
'// into the group, which makes things a bit more
'// complicated!
End If
End If
Next shp
Call m_restoreShape
Cleanup:
Set shp = Nothing
Set pg = Nothing
End Sub
Private Sub m_restoreShape()
If (m_visShpMouseDown Is Nothing) Then Exit Sub
'// Restore the shape's original lineweight:
m_visShpMouseDown.CellsU("LineWeight").FormulaU = m_lineWeightFormulaU
'// Clear the mouse-down variables:
Set m_visShpMouseDown = Nothing
m_lineWeightFormulaU = vbNullString
End Sub

Related

How to keep a button in access form disabled after one click using VBA

I am trying to code a button that allows user to only click once. I have managed to disable the button after one click but when I reopen the form the button is still enabled.
How can I keep the button disabled after one click. Ultimately I want to make ACCDE containing a form that has a button which is only enabled once. the ACCDE file will be used to for different projects and every time when starting a new project a copy of the generic ACCDE file will be used. The button needs to be internally enabled for every time you start a new project (i.e open a generic copy of the ACCDE) and becomes disabled after the user has clicked on it and remain disable forever for that particular project.
I managed to do the following coding for that button.
Private Sub Command21_Click()
DoCmd.OpenQuery "Reset AutoCounter"
Command21.Enabled = False
Command25.SetFocus
End Sub
The code above disables the button after one click, but when you close the form and reopen it the button comes as enabled.
Is there a code that I can use to keep the button disabled.
You can use TempVars for this:
Private Sub Form_Open()
If IsNull(TempVars("ProjectEnabled").Value) Then
' Initialise.
TempVars.Add "ProjectEnabled", True
End If
Me!Command21.Enabled = TempVars("ProjectEnabled").Value
End Sub
Private Sub Command21_Click()
Command25.SetFocus
DoCmd.OpenQuery "Reset AutoCounter"
Command21.Enabled = False
TempVars "ProjectEnabled", False
End Sub
Edit
Testing shows, that the above doesn't work as TempVars are not persistent.
So the simple workaround is to create a small local table with a Boolean field with DefaultValue of True, and then update this to False when clicking the button.
you either do it at design time:
in VBA IDE select the wanted UserForm from Project View and have it appear in the main code pane
select its Command21 control
in Properties View (F4 to pop it out) set its Enabled property to False
or, do it at runtime
insert this in your UserForm code pane :
Private Sub UserForm_Initialize()
Command21.Enabled = False
End Sub
Create a local table and make it hidden.
Use a value from that table to determine whether to hide enable it or not on either form load or application load (using a global variable).

MS Access POS (point of sale) application - Dynamically populate a form from a list

I need to create a small MS Access touchscreen POS (point of sale) application.
If someone has a rudimentary touchscreen MS Access template they can point me to, so that I can learn from it, that would help tremendously.
I have been able to find code for a touchscreen keyboard, which I will use.
The person using the interface needs to click on the name of a person as part of the POS process. The people change often, so I need to update the list often.
I am looking for a way to use VBA to create the onscreen buttons dynamically based on a list of people I update in a separate form.
The form will naturally be full-screen, and will never have more than 50 buttons on the screen representing the list of people. Only a few (less than 5) other controls will be present on this form, so the buttons representing the list of people needs to be constrained to an area on the form. The form must read the list of people, then create fixed sized, large square buttons automatically and be arranged alphabetically from left to right.
Thank you.
Something like this should work for you then. You'll need to make the max amount of buttons you will need on the form and space them and make an OnClick event for each like the one here for Command0. Then when the form is opened the array is initialized and all the buttons are captioned and made visible up to the amount of records in the table.
When each button is clicked it calls the HandleClick Sub to interact with the data as you need.
I made the recordset global so that it is only filled once and avoid weird data issues if the customers table is updated while this form is in use.
Dim Buttons(1 To 4) As Control
Dim rst As DAO.Recordset
Private Sub Command0_Click()
HandleClick (1) 'number that corresponds to this button in the array as
'initialized in the Form_Load sub, hard coded
End Sub
Private Sub Form_Load()
'initialize the buttons
Buttons(1) = Me.Command0
Buttons(2) = Me.Command1
Buttons(3) = Me.Command2
Buttons(4) = Me.Command3
Dim sql As String
sql = "SELECT * FROM tblCustomers"
Set rst = CurrentDb.OpenRecordset(sql)
FillButtons
End Sub
Sub FillButtons()
If (rst.EOF And rst.BOF) = False Then
rst.MoveFirst
Dim itr As Integer
Do
Buttons(itr).Caption = rst("CustomerName")
Buttons(itr).Visible = True
rst.MoveNext
Loop While rst.EOF = False
End If
End Sub
Sub HandleClick(CustomerNumber As Integer)
'Here is where you do what you intended with the button using
'customer number to know which record was clicked
End Sub
It's a messy approach but it should work.

LibreOffice Base; Tab order from mainform to subform

I have a form with a mainform and a subform. When the user is in the textbox, which is the closest to the subform, and the user press Tab, it has to jump into the subform, but it doesn't. It jumps to the textbox AFTER the subform. When the user is in the last textbox of the mainform and te user press tab, then it jumps into the subform.
How do I make sure, that the user will jump to the subform when he is in the textbox, which is the closest one to the subform?
Example image:
Tab order in the UI does not account for controls on subforms, but this can be done programmatically. Set a LO Basic macro on the When losing focus Event for the control that is closest to the grid/table control on the subform. That is the control that, when you tab past it, you want to go to the grid. For that event, run a macro like this, where grid1 is the table/grid control:
root_doc = ThisComponent
form_container = root_doc.Drawpage.Forms
form_ctrlr = root_doc.getCurrentController()
sub_frm = form_container.getByName("Sub_Form")
tab_target = sub_frm.getByName("grid1")
form_ctrlr.getControl(tab_target).setFocus()
You also will need to set up a similar macro when leaving grid1 as, because it is in the subform, it is not accounted for in the tab order.
Hat tip to probe1#ooForum.
I had to add one more line to get the code to work. See code.
Dim root_doc As Object
Dim form_container, form_ctrlr As Object
Dim main_frm, sub_frm, sub_frm_grd As Object
root_doc = ThisComponent
form_container = root_doc.Drawpage.Forms
form_ctrlr = root_doc.getCurrentController()
main_frm = form_container.getByName("MainForm")
sub_frm = main_frm.getByName("SubForm")
sub_frm_grd = sub_frm.getByName("SubForm_Grid")
'set focus to grid control
form_ctrlr.getControl(sub_frm_grd).setFocus()

VBA Excel: How can I make one form change the position of another form?

I have two forms, frmPE and frmCRE. They are modal.
frmCRE has a button "Edit PE" that will open formPE (instance of frmPE).
If I don't play with the positions, formPE opens centered on top of frmCRE.
I would like to position them side by side so I can see both at once.
When I open frmPE, I can still see frmCRE but not touch it. That's OK.
' This code is in cmdEditPE
Set formPE = New frmPE
Load formPE
If Not formPE.bInitialize(vbFalse) Then Err.Raise glHANDLED_ERROR
Me.Left = 100 ' move frmCRE to the left so I can see it
formPE.Left = Me.Left + Me.Width ' move frmPE to move to the right side of frmCRE (bad)
formPE.Show
I think the problem is that when formPE opens, it uses its default left setting. From within PE, I can see that me.Left = 0 even though it was set before the show.
Is there a way I can use the formPE.bInitialize routine to see that frmCRE is open and find out its LEFT and WIDTH so I can set formPE.Left correctly, or a way I can set it from frmCRE as I was trying to do above?
Thanks
Shari
Use the Activae event of frmPE to move itself, but only if frmCRE is visible.
In frmPE
Private Sub UserForm_Activate()
If frmCRE.Visible Then
Me.Left = frmCRE.Left + frmCRE.Width
End If
End Sub

Move FlowLayoutPanel Controls via DragDrop

I have a FlowPanelLayout that can contain several UserControls called DataGridViewFilterSortElement. These controls look kind of like buttons, but different. I want the user to be able to click one of the DataGridViewFilterSortElement controls and drag it to another position (index) in the FlowLayoutPanel.
Is there a way to see the control physically moving as the user drags it to another position? In other words, is there a way to take a "snap shot" of the control that is being dragged (instead of a shadowed box) which would show the actual control moving as the cursor moves? Also, as the control is being dragged I'd like to have the other controls position to shift automatically instead of waiting for the user to drop the drag to see the shifts.
For example, let's say the FlowPanelLayout contains 3 controls and the user wants to drag the first control to the third controls position. So the user clicks and holds the first DataGridViewFilterSortElement, then drags over the second control, which causes the second control to shift to position 1 of 3, then the user drags over the third control, which causes the third control to shift to position 2 of 3, then the user drops the control in position 3. Is this possible? The little code I do have is below.
Here is a short little video that shows what I want to do: http://www.youtube.com/watch?v=YhyTni6KH0Q
Private Sub lblDescription_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown, lblDescription.MouseDown
' if the user left clicks and holds the element begin a DragDrop action
If e.Button = Windows.Forms.MouseButtons.Left Then
Me.DoDragDrop(Me, DragDropEffects.Move)
End If
End Sub
Private Sub SortFlowLayoutPanel_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragOver
e.Effect = DragDropEffects.Move
End Sub
Private Sub SortFlowLayoutPanel_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles SortFlowLayoutPanel.DragDrop
If e.Data.GetData(GetType(DataGridViewFilterSortElement)) IsNot Nothing Then
'Current Position
Dim myIndex As Integer = Me.SortFlowLayoutPanel.Controls.GetChildIndex(CType(e.Data.GetData(GetType(DataGridViewFilterSortElement)), DataGridViewFilterSortElement))
'Dragged to control to location of next picturebox
Dim element As DataGridViewFilterSortElement = CType(e.Data.GetData(GetType(DataGridViewFilterSortElement)), DataGridViewFilterSortElement)
Me.SortFlowLayoutPanel.Controls.SetChildIndex(element, myIndex)
End If
End Sub
Private Sub SortFlowLayoutPanel_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles SortFlowLayoutPanel.DragOver
e.Effect = DragDropEffects.Move
End Sub
This page explains how to do what you want. I tried it, looks pretty good.
http://www.vbdotnetforums.com/gui/45818-flowlayoutpanel-repositioning-object.html