So I tried with
cursor.Clip = New Rectangle (desired coordinates)
But for some reason, it doesn't seem to work. I don't know what I'm doing wrong. It works on 2 sides (right and bottom), but it doesn't work on the other sides. But not even on the left side it is on the right coordinate, where I set the Rectangle.
How can I work this out?
Make sure your values for the Rectangle are in screen coords. For example, the following code will clip the cursor to Button2 when Button1 is clicked:
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Cursor.Clip = Me.RectangleToScreen(Button2.Bounds) ' confine cursor to the second button
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
Cursor.Clip = Nothing ' release the clip
End Sub
End Class
Related
I am trying to create two tables which mirror changes made to any of them to one another automatically.
To that end, I added event listeners which are triggered when the cells of these tables are edited by the user.
Unfortunately, editing one of the tables causes LibreOffice to crash, even though the changes are indeed reflected correctly, as seen upon reopening the file.
I thought the crash might be due to a never-ending circular reference, but it still crashes after it has been made non-circular (by commenting out the relevant parts of the code so that changes are reflected only one way rather than both ways).
I noticed the code worked fine when writing to a cell that didn't have an event listener set to it.
How can I write to one of the cells with event listeners set to them without causing LibreOffice to crash?
You may want to download the following file. Please run Main and then try editing the cell C3 of the Planning sheet. The arbitrary string "C" should be written in the cell C4 of the Services sheet.
Here is a simplified version of the code :
REM ***** BASIC *****
const SERVICESSHEET_NUMBER = 2
const SERVICESSHEET_SERVICES_COLUMN = 2
Type cellStruct
columnNumber As Integer
rowNumber As Integer
End Type
Sub UpdateServicesSheet(editedCell As cellStruct, newValue As String)
Dim oSheets
Dim servicesSheet
oSheets = ThisComponent.getSheets()
servicesSheet = oSheets.getByIndex(SERVICESSHEET_NUMBER)
servicesSheet.getCellByPosition(SERVICESSHEET_SERVICES_COLUMN, 3).setString(newValue)
End Sub
Private oListener, cellRange as Object
Sub AddListener
Dim sheet, cell as Object
sheet = ThisComponent.Sheets.getByIndex(0) 'get leftmost sheet
servicesSheet = ThisComponent.Sheets.getByIndex(2)
cellRange = sheet.getCellrangeByName("C3")
oListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener") 'create a listener
cellRange.addModifyListener(oListener) 'register the listener
cellRange = servicesSheet.getCellrangeByName("C4")
oListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener") 'create a listener
cellRange.addModifyListener(oListener) 'register the listener
End Sub
global CircularReferenceAllowed As boolean
Sub Modify_modified(oEv)
Dim editedCell As cellStruct
Dim newValue As String
editedCell.columnNumber = 2
editedCell.rowNumber = 2
If CircularReferenceAllowed Then
CircularReferenceAllowed = false
UpdateServicesSheet(editedCell, "C")
End If
End Sub
Sub Modify_disposing(oEv)
End Sub
Sub RmvListener
cellRange.removeModifyListener(oListener)
End Sub
Sub Main
CircularReferenceAllowed = true
AddListener
End Sub
Crossposted to :
OpenOffice forums
LibreOffice discourse platform
It seems like the event trigger is within another event's function is causing the crash. In any case, the solution is to remove the listener, then add it back after modifying the other cell.
You do need to global the Listener and the Cell objects to make this work.
This code is simplified to work on C3 and C15 on the first sheet. It would also output some information on C14, which isn't really necessary for your purpose, but I use it to see what's happening. You need to adopt the according to what you need.
global goListener as Object
global goListener2 as Object
global goCellR as Object
global goCellR2 as Object
global goSheet as Object
global giRun as integer
global giUpd as Integer
Sub Modify_modified(oEv)
Dim sCurStr$
Dim sNewStr As String
'xRay oEv
giRun = giRun + 1
sCurStr = oEv.source.string
oCell = goSheet.getCellByPosition(2, 14)
If (oCell.getString() <> sCurStr) Then
' only update if it's different.
giUpd = giUpd + 1
goCellR2.removeModifyListener(goListener2)
oCell.setString(sCurStr)
goCellR2.addModifyListener(goListener2)
End If
sNewStr =sCurStr & " M1 Run=" & giRun & " Upd=" & giUpd
goSheet.getCellByPosition(2, 13).setString(sNewStr)
End Sub
Sub Modify2_modified(oEv)
Dim sCurStr$
Dim sNewStr As String
Dim oCell as Object
'xRay oEv
giRun = giRun + 1
sCurStr = oEv.source.string
oCell = goSheet.getCellByPosition(2, 2)
If (oCell.getString() <> sCurStr) Then
' only update if it's different.
giUpd = giUpd + 1
goCellR.removeModifyListener(goListener)
oCell.setString(sCurStr)
goCellR.addModifyListener(goListener)
End If
sNewStr =sCurStr & " M2 Run=" & giRun & " Upd=" & giUpd
goSheet.getCellByPosition(2, 13).setString(sNewStr)
End Sub
Sub Modify_disposing(oEv)
MsgBox "In Modify_disposing"
End Sub
Sub Modify2_disposing(oEv)
MsgBox "In Modify2_disposing"
End Sub
Sub RmvListener
MsgBox "In RmvListener"
goCellR.removeModifyListener(goListener)
goCellR2.removeModifyListener(goListener2)
End Sub
Sub AddListener
goSheet = ThisComponent.Sheets.getByIndex(0) 'get leftmost goSheet
'servicesSheet = ThisComponent.Sheets.getByIndex(2)
goCellR = goSheet.getCellrangeByName("C3")
goListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener") 'create a listener
goCellR.addModifyListener(goListener) 'register the listener
goCellR2 = goSheet.getCellrangeByName("C15")
goListener2 = createUnoListener("Modify2_","com.sun.star.util.XModifyListener") 'create a listener
goCellR2.addModifyListener(goListener2) 'register the listener
End Sub
Sub Main
giRun = 0
giUpd = 0
AddListener
End Sub
I created a matlab GUI using GUIDE.
I created several panels with static text boxes inside them. I would like to write values to all the boxes once I push an "update" pushbutton.
for instance, I would like to write to a box with tag AV1, and the text box is inside panel "uipanel2".
Both ways give errors:
set(handles.AV1,'String','hi');
The above code does not work as it says the field does not exist. This makes sense as I need to access the panel first.
So below I access the panel, but how do I get to its children?
set(handles.uipanel2.AV1,'String','hi');
this code gives the following error: Attempt to reference field of non-structure array.
Children is a field so if you want the children you can try get(handles.uipanel2,'Children') and it will give you an array with handles to the children. It will look like numbers to you in the same way that the handle to uipanel2 looks like a number.
Here's an example:
function testGUI
fig = figure(1);
panel = uipanel(fig);
tbox = uicontrol('Style','text','String','hello','parent',panel);
ch = get(panel,'Children')
get(ch,'Type')
get(ch,'String')
end
It shows how to get the Children of the panel object with ch = get(panel,'Children') which should print something to console that looks like:
ch =
182.0011
And to show you that this ch is in fact a handle to the static textbox that is a child of the panel, I've printed out the type and string of ch to console which should be the following:
ans =
uicontrol
ans =
hello
And here's an example of how to get the string in a textbox to update when you press a Push Button:
function testGUI
fig = figure(1);
panel = uipanel(fig);
tbox = uicontrol('Style','text','String','hello','parent',panel);
button = uicontrol('Style','PushButton','String','push me',...
'Position',[100 100 50 25]);
set(button,'Callback',#mycallback)
function mycallback(src,eventdata)
set(tbox,'String','updated')
end
end
I learned getting the image size using itextsharp pdf
the image size is the physical dimension before the image was inserted in the pdf.
Dim iwidth As Integer = tg.GetAsNumber(PdfName.WIDTH).IntValue
Dim iheight As Integer = tg.GetAsNumber(PdfName.HEIGHT).IntValue
When I extracted the image is very large, larger than the paper size.
But if you view the image inside the pdf with any pdf reader software, the image is small.
How can I get the designed image size inside the pdf?
Im using this code and I don't know if is the proper, I don't know the next think to do.
Dim pdfDesignedImage As iTextSharp.text.pdf.parser.InlineImageInfo
This is my 2nd account, I was wrong on first. Sorry about that.
I hope I can be better using this account.
There's a poorly named Interface called ITextExtractionStrategy that you can implement that will give you extended information when extracting things from a PDF. I say "poorly named" because although it says "text" it also supports images as well. This interface has 5 methods, 4 of which are text-based and you can just ignore. The method that you are interested in is RenderImage. Below is a full working implementation of this:
Public Class ImageInfoTextExtractionStrategy
Implements iTextSharp.text.pdf.parser.ITextExtractionStrategy
#Region " Extra Methods - Just Ignore "
Public Sub BeginTextBlock() Implements iTextSharp.text.pdf.parser.IRenderListener.BeginTextBlock
End Sub
Public Sub EndTextBlock() Implements iTextSharp.text.pdf.parser.IRenderListener.EndTextBlock
End Sub
Public Sub RenderText(renderInfo As iTextSharp.text.pdf.parser.TextRenderInfo) Implements iTextSharp.text.pdf.parser.IRenderListener.RenderText
End Sub
Public Function GetResultantText() As String Implements iTextSharp.text.pdf.parser.ITextExtractionStrategy.GetResultantText
Return Nothing
End Function
#End Region
''//We'll add all image rectangles to this collection
Private _AllImageRectangles As New List(Of iTextSharp.text.Rectangle)
Public ReadOnly Property AllImageRectangles As List(Of iTextSharp.text.Rectangle)
Get
Return Me._AllImageRectangles
End Get
End Property
Public Sub RenderImage(renderInfo As iTextSharp.text.pdf.parser.ImageRenderInfo) Implements iTextSharp.text.pdf.parser.IRenderListener.RenderImage
''//Get the image's matrix
Dim m = renderInfo.GetImageCTM()
Dim w, h, x, y As Single
''//Get the various parameters from the matrix
w = m(iTextSharp.text.pdf.parser.Matrix.I11)
h = m(iTextSharp.text.pdf.parser.Matrix.I22)
x = m(iTextSharp.text.pdf.parser.Matrix.I31)
y = m(iTextSharp.text.pdf.parser.Matrix.I32)
''//Turn the parameters into a rectangle
Me._AllImageRectangles.Add(New iTextSharp.text.Rectangle(x, y, x + w, y + h))
End Sub
End Class
To use this subclass we pass it to the (once again poorly named) method iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(). Normally you'd call this method and assign the string result to a variable but in our case we don't care about the text so don't. To use it you would do this:
''//Path to our pdf with images
Dim PdfWithImage = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "PdfWithImage.pdf")
''//Bind a reader to our PDF
Dim reader As New PdfReader(PdfWithImage)
''//Create an instance of our custom extraction class
Dim strat As New ImageInfoTextExtractionStrategy()
''//Loop through each page in our PDF
For I = 1 To reader.NumberOfPages
''//The GetTextFromPage method does the work even though we are working with images
iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(reader, I, strat)
Next
''//Get all image rectangles found
Dim Rects = strat.AllImageRectangles
For Each R In Rects
''//Do something with your rectangles here
Next
So I have a bunch of listboxes on my VB form. I created a command button too.
I want to make it so that if I press the command button it cycles from the current listbox, which has focus, to the previous listbox. It's the equivalent of using TAB and SHIFT TAB to cycle amongst the control. SHIFT TAB goes backwards in the cycle, TAB goes forward in the cycle. I vaguely remember there was a way to go back & forth in the "tab cycle".
How do I do this?
You can;
Private mCurrentListboxTabIndex As Integer
'wire up, simpler if you use a control array
Private Sub List1_GotFocus()
mCurrentListboxTabIndex = List1.TabIndex
End Sub
Private Sub List2_GotFocus()
mCurrentListboxTabIndex = List2.TabIndex
End Sub
Private Sub List3_GotFocus()
mCurrentListboxTabIndex = List3.TabIndex
End Sub
Private Sub btnPrev_Click()
FocusListBoxByTabIndex -1
End Sub
Private Sub btnNext_Click()
FocusListBoxByTabIndex 1
End Sub
Private Sub FocusListBoxByTabIndex(offset As Long)
Dim ctrl As VB.Control
For Each ctrl In Me
If TypeOf ctrl Is ListBox Then
If ctrl.TabIndex = mCurrentListboxTabIndex + offset Then
ctrl.SetFocus
Exit Sub
End If
End If
Next
End Sub
I would like to execute some code when a user closes a form using the x button in the top right corner of the window (I have the form load when the excel spreadsheet is opened, and it hides Excel. I want to exit excel once the form is closed, or at least show excel again so the user may exit it manually)
Looking at the form properties, the Unload property is not present, nor am I able to figure out how to make a function which executes when the form is closed.
Unfortunately, coding this in VB is not an option, it must be VBA.
I'm aware of the code needed to unhide Excel or quit it outright, just not how to tie it to the unload event.
You can use QueryClose event of the UserForm as follows:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then
' Your codes
' Tip: If you want to prevent closing UserForm by Close (×) button in the right-top corner of the UserForm, just uncomment the following line:
' Cancel = True
End If
End Sub
You can also use vbFormControlMenu like this:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
'Your code goes here
End If
End Sub
A colleague was able to provide the answer, including example here for everybody else
Private Sub userform_terminate()
'Code goes here
End Sub
You can use Unload Me in VBA to close a form. Just put the code to close Excel immediately following that.
Private Sub Form_Unload(Cancel As Integer)
Dim msgRes As VbMsgBoxResult
msgRes = MsgBox("Exit form ?", vbYesNo)
If msgRes = vbYes Then
'optional code
ElseIf msgRes = vbNo Then
Cancel = True
End If
End Sub
I was able to prevent the form from closing when the X button was click using the following:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Cancel = MsgBox("Please confirm cancellation", vbOKCancel + vbQuestion) = vbCancel
End Sub
try something like this:-
Private Sub Form1_FormClosing(sender as Object, e as FormClosingEventArgs) _
Handles Form1.FormClosing
//Code you want to execute
End Sub