How To Resize AutoCAD Palette Set - vb.net

Goal
Resize the palette set on plugin start up so that it looks like so:
Everything is correctly adjusted here and looks nice. This setup is saved when I close AutoCAD manually. Although, my goal would be to make the program make it start up like this.
Current Start-Up Result
Here's the result I get on start up:
As you can see, it's not wide enough. The width needs to get larger but the height is correctly set.
Current Attempt
Here is what I have when starting up my application:
<CommandMethod("Hunter-P")> _
Public Sub HunterP()
'Tool Palette
If ps Is Nothing Then
ps = New Autodesk.AutoCAD.Windows.PaletteSet("Hunter Palette Set", "", New Guid("{ECBFEC73-9FE4-4aa2-8E4B-3068E94A2BFA}"))
ps.Style = Autodesk.AutoCAD.Windows.PaletteSetStyles.ShowPropertiesMenu Or Autodesk.AutoCAD.Windows.PaletteSetStyles.ShowAutoHideButton Or _
Autodesk.AutoCAD.Windows.PaletteSetStyles.ShowCloseButton
projPalette = New tpProjectToolPalette(Me)
convPalette = New tpConveyorToolPalette(Me)
ps.Add("Projects", projPalette)
ps.Add("Conveyors", convPalette)
End If
ps.Visible = True
ps.Dock = Autodesk.AutoCAD.Windows.DockSides.Left ' Docks the palette set to the left
ps.Size = New System.Drawing.Size(350, 800) 'Sets the width and height
convPalette.Visible = False
'Activate Project ToolPalette
ps.Activate(0)
If m_DocData Is Nothing Then
m_DocData = New MyDocData
End If
AddHandler AcApp.DocumentManager.DocumentActivated, AddressOf Me.DocumentManager_DocumentActivated
AddHandler AcApp.DocumentManager.DocumentToBeDeactivated, AddressOf Me.DocumentManager_DocumentToBeDeactivated
End Sub
This result seems to not actually dock the palette set. There is unwanted space at the bottom.
How do we resize a palette set correctly?

I solved this issue by switching around my Dock and Size lines.
It becomes possible to resize it like so (while keeping it docked left)
ps.Size = New System.Drawing.Size(335, 600) 'Resizing
ps.Dock = Autodesk.AutoCAD.Windows.DockSides.Left
This solved my issue.

Related

Image won't change in picturebox, vb.net

I'm trying to code it so that i can create a picture box from a method in a class. However when my picture box is drawn it doesn't display any image, it only shows a white square of the specified dimensions in the specified location.
Here is the code which i am using to create said picture box:
Public Sub DrawEnemy(ByRef formInstance)
Dim enemypic As New PictureBox
enemypic.Image = Image.FromFile("C:\fboi1\Enemy.Png")
enemypic.Width = 64
enemypic.Height = 64
enemypic.Location = New Point(Me.EnemyPosX, EnemyPosY)
enemypic.Visible = True
formInstance.Controls.Add(enemypic)
End Sub
And here is where i am calling the method from:
Dim Enemy1 As New computerControlled(1, 1)
Enemy1.DrawEnemy(Me)
Please add the following code in your DrawEnemy() method:
enemypic.SizeMode = PictureBoxSizeMode.StretchImage
When i drag the console window suddenly the white box turns into the image i wanted.
Aha! This means the code is not causing the form to be repainted. We can trigger that by calling the Invalidate() function.
Public Sub DrawEnemy(formInstance As Form)
Dim enemypic As New PictureBox
enemypic.Image = Image.FromFile("C:\fboi1\Enemy.Png")
enemypic.Width = 64
enemypic.Height = 64
enemypic.Location = New Point(Me.EnemyPosX, EnemyPosY)
enemypic.Visible = True
formInstance.Controls.Add(enemypic)
formInstance.Invalidate()
End Sub
If you're calling this several times in a loop, you would instead handle this after the loop, where you also block repainting (to prevent flickering) until the loop is finished.
form.SuspendLayout()
For Each enemy In ...
'...
DrawEnemy(form)
Next
form.Invalidate()
form.ResumeLayout()
It's also possible you only need to Invalidate() the picturebox.

Capture Active Window with Keyboard SendKeys

After experiencing problems with Visual Basic's printform quality, I have decided to take a different approach. I am going to simulate an ALT-PRINTSCREEN keyboard key-press to capture the form in its current state.
However, before this happens, I need to remove certain elements from the form (such as the border), and after getting the image, I need to replace these elements. I am having some timing/synchronization problems with this, as I am noticing that certain elements are still on the image that has been copied to the clipboard.
I figured this was due to the fact that it takes time to process the changes, and time for Windows to process the simulated "send keys", so I set up sleep timers. I am having mixed results. I notice that if I don't replace the elements afterwords, the clipboard image appears correctly. However, if I do replace them, even if I set up a 20 second sleep timer, they do not appear.
Therefore, I know there is some sort of synchronization problem, but I am not sure how to fix it. Here is the code I am using:
'Make these forms invisble so they are not printed
Logo.Visible = False
MenuStrip1.Visible = False
ReportsButton.Visible = False
pnlmain.BorderStyle = 0 'remove the border
'Sleep
System.Threading.Thread.Sleep(1000)
'simulate an ALT and PRINTSCREEN key click to get ONLY the report
SendKeys.Send("%{PRTSC}")
'Sleep
System.Threading.Thread.Sleep(1000)
'Now, get the image from the clipboard
Dim formImage As System.Drawing.Image
formImage = My.Computer.Clipboard.GetImage()
Logo.Visible = True
MenuStrip1.Visible = True
ReportsButton.Visible = True
pnlmain.BorderStyle = 1
Changing the sleep durations does not seem to change much (unless they are very low).
Any suggestions?
EDIT: here is the code for draw to bitmap (after modifying the code above):
formImage = New Bitmap(Me.Width, Me.Height, Me.CreateGraphics())
Me.DrawToBitmap(formImage, New Rectangle(0, 0, Me.Width, Me.Height))
When it is sent to the print action:
Dim g As Graphics = e.Graphics
'transform the form image so it fits the height and width of the paper, with a 5 px margin
Dim res = printSettings.PrinterResolutions
Dim newSizeDestinationPoints As Point() = {
New Point(5, 5),
New Point(841, 5),
New Point(5, 956)
} 'These values are based on A4 sized paper
'g.DrawImage(formImage, 5, 5)
g.DrawImage(formImage, newSizeDestinationPoints)
The low quality is not coming from the stretch.

How to get Winforms Panel to correctly layout many items?

I've got a WinForms Panel control which holds a large number of child controls. Each child is left docked, causing the horizontal width of the contents to grow. The containing Panel has its AutoScroll property set so that you can get to all the contents.
I'm running into a problem when the total width of the contents gets too large. Once you've hit this maximum width, additional content elements are placed on top of existing contents instead of being placed to the right. But, if I resize the Panel after it has done its initial layout, it corrects itself by expanding its logical width and placing each content element in the correct location. How do I get it to layout correctly before the user resizes the window?
Here's a simple example:
Form1.vb
Public Class Form1
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
For i As Integer = 1 To 200
Dim gb As New GroupBox
gb.Text = "Box " & i.ToString
gb.Width = 250
gb.Dock = DockStyle.Left
Panel1.Controls.Add(gb)
gb.BringToFront()
Next
End Sub
End Class
Form1.Designer.vb
Partial Class Form1
Inherits System.Windows.Forms.Form
Private Sub InitializeComponent()
Me.Panel1 = New System.Windows.Forms.Panel()
Me.SuspendLayout()
'
'Panel1
'
Me.Panel1.AutoScroll = True
Me.Panel1.Dock = System.Windows.Forms.DockStyle.Fill
Me.Panel1.Location = New System.Drawing.Point(0, 0)
Me.Panel1.Name = "Panel1"
Me.Panel1.Size = New System.Drawing.Size(284, 262)
Me.Panel1.TabIndex = 0
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(284, 262)
Me.Controls.Add(Me.Panel1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub
Friend WithEvents Panel1 As System.Windows.Forms.Panel
End Class
This is what the window looks like when it first comes up, scrolled nearly to the end so you can see the problem area. Notice that Box 183 to 199 are missing because they are placed on top of each other. This is not right.
This is what the window looks like after you manually resize it, scrolled nearly to the end. The panel fixed itself in response to the resize; the total logical width of the panel was automatically extended enough to hold all the contents. This is what I want it to look like when it first comes up.
I've tried manually setting the location of each box, and I've tried calling PerformLayout() and several other functions. Nothing seems to work. So far I haven't found the magic combination to get the good layout. Does anyone know how to fix this?
Edit:
Here's a screenshot that might make the issue more obvious. I adjusted the box widths and the number of boxes to show the problem better. See how the last box overlaps box 656? Every box from 657 to 700 has the same incorrect location. Turning off docking and setting the location myself doesn't help.
Looks like a bug with the scrolling information. If you call PerformLayout when the Panel is scrolled all the way to the right, it correctly places the controls in the proper place. That requires some code in the OnShown method:
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
Panel1.AutoScroll = True
Panel1.SuspendLayout()
For i As Integer = 1 To 200
Dim gb As New GroupBox
gb.Text = "Box " & i.ToString
gb.Width = 250
gb.Dock = DockStyle.Left
Panel1.Controls.Add(gb)
gb.BringToFront()
Next
Panel1.ResumeLayout(False)
End Sub
Protected Overrides Sub OnShown(e As EventArgs)
MyBase.OnShown(e)
Panel1.AutoScrollPosition = New Point(Panel1.HorizontalScroll.Maximum - _
Panel1.HorizontalScroll.LargeChange, 0)
Panel1.PerformLayout()
Panel1.AutoScrollPosition = Point.Empty
End Sub
Of course, having over 200 container controls on the form is never recommended.
AutoScroll is not AutoPositionMyChildren. From MSDN:
When adding controls programmatically to a form, use the AutoScrollPosition property to position the control either inside or outside of the current viewable scroll area.
If you looped thru the controls, to print their location, you's see at some point (probably around 130) that Location.Y becomes fixed at 32767 probably some default unscrolled max. This is also the point they start stacking because they in fact have the same initial location. Some of the code you have makes up for that but it isnt quite right. Once you scroll it, the panel fixes the coords on the child controls.
First, I would suggest that you set Panel1.AutoScrollMinSize to something like {480, 0} so that the HScroll bar appears at design time; this allows you to calc a good height for the boxes which wont cause a VScroll as you add controls.
Dim gb As GroupBox
' only 150 because problem is when (i * width) > 32k
For i As Integer = 0 To 150
gb = New GroupBox
gb.Name = i.ToString ' added
gb.Text = "Box " & i.ToString
gb.Width = 250
' no docking so set the height
gb.Height = Panel1.Bounds.Height - 30 ' trying to avoid the VSCroll
' set location explicitly
gb.Location = NewCtlLocation(Panel1.Controls.Count,
Panel1.AutoScrollPosition.X)
' Dock and Anchor mess up the AutoScroll
'gb.Dock = DockStyle.Left
Panel1.Controls.Add(gb)
' allow panel to update its scroll positions
Panel1.ScrollControlIntoView(gb)
' not needed; seems to offset something with Dock
' changing ZOrder may not always be desirable
'gb.BringToFront()
' debug illumination
Console.WriteLine("{0} {1} {2}", i.ToString,
Panel1.AutoScrollPosition.X.ToString,
gb.Location.X.ToString)
Next
'Go back to start
Panel1.ScrollControlIntoView(Panel1.Controls("0"))
Location helper so you can tweak gutters or margins (dock replacement):
Friend Function NewCtlLocation(ByVal n As Integer,
ByVal ScrollPosX As Integer) As Point
Const TopMargin As Integer = 5
Const LeftMargin As Integer = 5
Return New Point((n * 250) + ScrollPosX, 0)
End Function
Notes:
I have a vertical scroller which repeatedly adds up to 120 user controls which works well but it does not need/use ScrollControlIntoView and they never stack up like yours do. I suspect maybe because they are smaller. There is also at least a second or two before the next one can be added, which may matter. But, good to know.
It might be possible to use the ControlAdded event of the panel to do something, but it would likely amount to ScrollControlIntoView. Doing it once at the end only doesnt work, so using it as they are added is allowing something to get updated as you go.
With the right fiddling, you might be able to get Dock to work, but I suspect it may be part of the problem such as Height and Left set this way dont update the panel's internal scroll map.
Your boxes actually look narrower than 250 - is autosize on?
Suspend/Resume Layout hurt rather than help - they prevent the control from doing anything about the virtual area being populated. It should happen fast enough that no one will see anything. Results:
Works on My SystemTM

Table layout panel inc#

I have to create dynamic table layout panel with some controls with auto sized rows and and fixed columns size.
My problem is that i want to show whole checkbox text .
Any help
My code is
Dim textBox2 As New CheckBox()
textBox2.Text = "You forgot to add the ColumnStyles. Do this on a sample form first with the designer. Click the Show All Files icon in the Solution Explorer window. Open the node next to the form and double-click the Designer.vb file. "
textBox2.AutoSize = True
textBox2.Dock = DockStyle.Top
'' textBox2.Size = New Point(200, 90)
Dim lbl1 As New Label()
lbl1.Location = New Point(10, 10)
lbl1.Text = "Yoer.vb"
lbl1.AutoSize = True
lbl1.Location = New Point(120, 50)
lbl1.Dock = DockStyle.Top
'' dynamicTableLayoutPanel.Padding = New Padding(2, 17, 4, 5)
dynamicTableLayoutPanel.Controls.Add(lbl1, 0, 0)
dynamicTableLayoutPanel.Controls.Add(textBox2, 1, 0)
Me.dynamicTableLayoutPanel.SetColumnSpan(textBox2, 5)
If you mean you want the table to size to the controls within it, then:
dynamicTableLayoutPanel.AutoSize = True
I know this is old, but I stumbled across it and figured I'd throw my 2 cents in in case someone else comes along.
Note: I'm using Visual Studio 2015 with .NET 4.6. Functionality may differ between versions.
The problem is that the really long text is not word-wrapping to fit within the table or form. Instead, it is set to Dock = DockStyle.Top. This will cause it to make a single line that continues on and gets clipped, similar to a single-line textbox.
If you want it to automatically word wrap, you'll need to use Dock = DockStyle.Fill. Now, this doesn't completely resolve the problem if your row or table isn't large enough to display the text. Since all of the rows are set to AutoSize, it will only do the bare minimum to fit the control vertically. It doesn't care if text gets clipped off. The end result, using your example code against a 6-column, 10-row table, is this:
Since there isn't a word wrap property, you'll need to manually fit it. Now, to do this, you'll need to change the row to be Absolute instead of AutoSize. To figure out how big to make it, you can pretty much rely on PreferredSize. This reveals a much wider Width than the existing regular Width. From that, we can determine how many lines it would take if we wrap it.
This is what my code ended up looking like:
Dim h As Single = 0
Dim chk As New CheckBox()
chk.Text = "You forgot to add the ColumnStyles. Do this on a sample form first with the designer. Click the Show All Files icon in the Solution Explorer window. Open the node next to the form and double-click the Designer.vb file. "
chk.AutoSize = True
chk.Dock = DockStyle.Fill
Dim lbl1 As New Label()
lbl1.Text = "Yoer.vb"
lbl1.AutoSize = True
lbl1.Dock = DockStyle.Top
dynamicTableLayoutPanel.Controls.Add(lbl1, 0, 0)
dynamicTableLayoutPanel.Controls.Add(chk, 1, 0)
dynamicTableLayoutPanel.SetColumnSpan(chk, 5)
' Find the preferred width, divide by actual, and round up.
' This will be how many lines it should take.
h = Math.Ceiling(chk.PreferredSize.Width / chk.Width)
' Multiply the number of lines by the current height.
h = (h * chk.PreferredSize.Height)
' Absolute size the parent row to match this new height.
dynamicTableLayoutPanel.RowStyles.Item(0) = New RowStyle(SizeType.Absolute, h)
The changes included delaring a height variable, renaming the CheckBox variable, setting its Dock to Fill, removing the Location from lbl1, and adding in size calculation. The output:
This isn't perfect since the height includes the checkbox itself, and the checkbox takes up padding, so there can be too much or too little height calculated. There are other calculations that may need to be considered. But, this is a starting point.

Order of controls being added to panel, control not showing unless docked

I imagine this is probably an easy to answer question but for some reason I can't get it to work
Sub New(ByVal Sess As AudioSessionControl2)
S_Session = Sess
'Create the panel and position it.
S_Panel.BackColor = Color.AliceBlue
S_Panel.Width = 200
S_Panel.Height = 40
Dim Position As New Point(6, 19)
If G_AppSessions.Count > 0 Then
Position = Point.Add(G_AppSessions.Item(G_AppSessions.Count - 1).SessionPanel.Location, New Point(0, 45))
End If
S_Panel.Location = Position
'Create a label which has the name of the process
Dim S_PName As New Label
S_PName.Text = "Test"
S_PName.Dock = DockStyle.Left
S_Panel.Controls.Add(S_PName)
'Create a button to change volume
Dim S_Save As New Button()
S_Save.Text = "Save"
AddHandler S_Save.Click, AddressOf Save_Click
S_Save.Parent = S_Panel
S_Panel.Controls.Add(S_Save)
S_Volume.Parent = S_Panel
S_PName.Parent = S_Panel
MainForm.Controls.Add(S_Panel)
S_Panel.Parent = MainForm.gb_Applications
End Sub
The problem is that, the label will show because its docked, but the button won't. It will only show if its docked as well, and thats just not what I want. This is part of a class for creating a dynamic UI, where I can create a number of this class to create a bunch of panels for various things.
I don't see anywhere where you are setting the label or button position. You probably have them both at 0,0 and the label is on top of the button, obscuring it. Did you try setting the position of both the controls, making sure they don't overlap?