Changing image Appearance and BorderStyle only works sometimes? - image

I'm trying to use the Appearance and BorderStyle properties of the image control to provide a not selected/selected indicator.
After image is loaded and displayed in the not selected condition, I can change Appearance and BorderStyle to 1 and it displays properly. But subsequent changes of these properties back to 0 has no effect.
Public Sub SelectPic(obj As Object, SelectIt As Boolean)
Dim Val As Integer
If SelectIt Then
Val = 1 'this works
Else
Val = 0 'this doesn't work
End If
obj.Appearance = Val
obj.BorderStyle = Val
obj.Refresh
End Sub
If I load a .bmp file into an image with flat appearance and no border, the image displays in agreement with the .bmp sizing info. But if load into an image with 3D appearance and single border, it displays according to the defined image size. Changing the properties back to flat and no border has no effect.

Related

Can I go below a VB6 TextBox control's minimum height enforced by the used font?

I have a TextBox control restricted to numeric input. Its font is Arial, Standard, 10 pt. The container's ScaleMode is set to pixels.
Since the textbox will accept and display only numbers, I do not need all that whitespace around, especially not in the vertical dimension, so I resize the TextBox' height in the designer. My goal is a 20 pixels tall TextBox control.
Attempting to set the Height property in the property window snaps the height to 24 pixels.
It is obvious, that the control's height is enforced by the used font. Using Arial, Standard, 7 pt., I can have my desired height of 20 px. Only that I need a font size of 10 pt.
When using the mouse, resizing works in the designer (for example can I achieve 19 pixels). But at run-time, the height is back to 24 pixels.
I've tried to trick VB in the Initialize event by first giving it a small font, sizing the height, then reset the font size to the original. Nope, 24 pixels.
I also tried to use Window's API function MoveWindow. The box displays at 24 pixels.
Is there any other possibly helpful API function, or is my only possibility to write an own VB user control? (I can make a user control consisting of a TextBox control as its only constituent control, then place its Top into the negative, and the user control's height to the desired height.)
Ok, so I went the stony road and created a user control suitable for me. Should you have the same problem, then this one solves it.
Add a new project of type ActiveX user control. Name the user control UTextBox. Modify the user control's font to what we want (Arial, Standard, 10 pt.), and set its ScaleMode property to pixels. Save the 2 files into a new project folder.
Place a TextBox control at position 0, 0 of the user control, and name it cTextBox. Then the whole core functionality is contained in the Resize event.
Option Explicit
'==============================================================================
'On resizing the control.
'------------------------------------------------------------------------------
Private Sub UserControl_Resize()
Dim lHeightDiff As Long
With cTextBox
'Let the TextBox control inherit the user control's new dimensions.
.Height = UserControl.ScaleHeight
.Width = UserControl.ScaleWidth
'The text box is always centered vertically on the same-sized or smaller
'user control, so that the text still is displayed also when the
'TextBox is larger than the user control's height.
.Top = (UserControl.ScaleHeight - .Height) / 2
End With
End Sub
'==============================================================================
Next is the tedious task to pass to and from the text box control all properties, methods and events, or at least all those you are interested in.
'==============================================================================
'Pass-through properties. Keep it alphabetical.
'------------------------------------------------------------------------------
Public Property Let Alignment(NewAlignment As AlignmentConstants)
cTextBox.Alignment = NewAlignment
PropertyChanged "Alignment"
End Property
'------------------------------------------------------------------------------
Public Property Get Alignment() As AlignmentConstants
Alignment = cTextBox.Alignment
End Property
'------------------------------------------------------------------------------
Public Property Let Enabled(NewState As Boolean)
cTextBox.Enabled = NewState
PropertyChanged "Enabled"
End Property
'------------------------------------------------------------------------------
Public Property Get Enabled() As Boolean
Enabled = cTextBox.Enabled
End Property
'------------------------------------------------------------------------------
Public Property Get hWnd() As Long 'Read-only.
hWnd = cTextBox.hWnd
End Property
'------------------------------------------------------------------------------
Public Property Let Text(NewText As String)
cTextBox.Text = NewText
PropertyChanged "Text"
End Property
...
'==============================================================================
There are (at least) two special properties which should be intercepted and applied onto the user control itself: Appearance and BorderStyle, because the text box can be placed outside the user control and would make these properties partially invisible. For these 2 properties, I was not able to locate their enumerations as shown in the property window, and consequently rolled own ones (there exists a naming convention, use your own names if you wish):
'==============================================================================
'Enumerations.
'------------------------------------------------------------------------------
'Used with the public Appearance property.
Public Enum ETxB_Appearance
TxBApp_2D = 0&
TxBApp_3D = 1&
End Enum
'------------------------------------------------------------------------------
'Used with the public BorderStyle property.
Public Enum ETxB_BorderStyle
TxBBSt_None = 0&
TxBBSt_FixedSingle = 1&
End Enum
'==============================================================================
These are the 2 special properties:
'==============================================================================
'All properties, methods and events which are currently needed are mediated
'to and from the outside world and the TextBox control, with the exception of
'BorderStyle and Appearance, which are properties of the user control, so that
'a frame can be displayed even when it would not fit into the TextBox control.
'------------------------------------------------------------------------------
Public Property Let Appearance(NewAppearance As ETxB_Appearance)
UserControl.Appearance = NewAppearance
PropertyChanged "Appearance"
End Property
'------------------------------------------------------------------------------
Public Property Get Appearance() As ETxB_Appearance
Appearance = UserControl.Appearance
End Property
'------------------------------------------------------------------------------
Public Property Let BorderStyle(NewStyle As ETxB_BorderStyle)
UserControl.BorderStyle = NewStyle
PropertyChanged "BorderStyle"
End Property
'------------------------------------------------------------------------------
Public Property Get BorderStyle() As ETxB_BorderStyle
BorderStyle = UserControl.BorderStyle
End Property
'==============================================================================
Now do the same for all methods.
And now for all events (and of course you need to add Event declarations as well.)
Finally, don't let's forget to happily code the property bag routines to make your user control have persistent properties.
'==============================================================================
'Initializing properties.
'------------------------------------------------------------------------------
Private Sub UserControl_InitProperties()
UserControl.Appearance = TxBApp_2D
...
cTextBox.Alignment = vbLeftJustify
...
End Sub
'==============================================================================
'==============================================================================
'Reading properties.
'------------------------------------------------------------------------------
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
With PropBag
UserControl.Appearance = .ReadProperty("Appearance", TxBApp_2D)
...
cTextBox.Alignment = .ReadProperty("Alignment", vbLeftJustify)
...
End With
End Sub
'==============================================================================
'==============================================================================
'Write properties.
'------------------------------------------------------------------------------
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
With PropBag
.WriteProperty "Appearance", UserControl.Appearance, TxBApp_2D
...
.WriteProperty "Alignment", cTextBox.Alignment, vbLeftJustify
...
End With
End Sub
'==============================================================================
Now the automatic minimum height enforcement is gone. For example can we fit our standard 10 pt Font into a 14 pixels tall control.

Form property automatically changing on saving changes in VB6 (configured with VSS 2005)

I am facing below issue in VB6 :
When I checkout file file and check "Show differences" it is showing no difference (identical files) but when I save my changes without changing and form property and again check for differences in VSS , it is showing difference in few property.One of them is mentioned below.Kindly suggest.
Begin VB.Label CommStatus
BackColor = &H80000014&
BorderStyle = 1 'Fixed Single
BeginProperty Font
**Name = "Arial"** 'this property is changing
Size = 8.25
Charset = 204
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
ForeColor = &H000000C0&
Height = 375
Left = 240
TabIndex = 3
ToolTipText = "The most recently detected error"
Top = 360
Width = 7815
End
You can check attach image
After looking in to this, the reason for seems to be Windows zoom setting (100%,125% and 150%, control panel/Make text and other items larger or smaller). If the form is checked in to TFS/VSS/GIT in one zoom setting, and later edited in another, VB6 will change all kind of form properties to adjust for this. So this probably only happens in dev teams with 2+ users that happens to have different screen sizes and therefor different zoom settings.
Only way to avoid this is probably to all use the same zoom setting...

Convert ico file to png Visual Basic

I am Looking for Code in VB that convert Ico File to other Format such as:
Jpg,JPEG,BMP,PNG
someone know such thing like that?
i tried it:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim ImageUrl As String
ImageUrl = "C:\Arto.ico"
Dim str As Integer
str = InStr(ImageUrl, ".ico")
If (str > 0) Then
Dim b As New Bitmap(ImageUrl)
Dim newurl = Mid(ImageUrl, 1, Len(ImageUrl) - 4)
newurl = newurl + ".jpg"
b.Save(newurl) <<<<error here
' newurl = Mid()
' b.Save()
End If
End Sub
and that it the error i got:
An unhandled exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll
Additional information: A generic error occurred in GDI+.
There is no image codec for icons. It is a pretty non-trivial format that can store multiple images and has 3 bitmaps for each image, one that contains the image pixels and two monochrome bitmaps that indicate which pixels are transparent and which are inverted. The Image class just doesn't have the plumbing in place to fully specify the properties that are needed to faithfully generate an .ico file.
But you're ahead since you want a PNG of JPEG file. You can create a bitmap that has the same size as the icon and draw the icon into that bitmap. A very important and non-trivial selection you need to make is choosing a background color for the image. Required because icons have transparency so you'll see the background on which it is displayed. Some image formats, like JPEG, don't support transparency. You have to pick one, Color.White tends to be okayish since that's the common background color for programs that display icons. You can use Color.Transparent for a PNG image.
Sample code:
Dim srce = "c:\temp\test.ico"
Dim dest = "c:\temp\test.jpg"
Using ico = New Icon(srce)
Using bmp = New Bitmap(ico.Width, ico.Height)
Using gr = Graphics.FromImage(bmp)
gr.Clear(Color.White) '' NOTE!
gr.DrawIcon(ico, 0, 0)
End Using
bmp.Save(dest, System.Drawing.Imaging.ImageFormat.Jpeg)
End Using
End Using

Change cell background color without changing focus

On a form I have 4 MSFlexGrids.
The top grid contains dynamic data, which updates once in a while.
The user can enter data in the cells of the 3 other grids.
The data which is used to fill the top grid is received via a Winsock control, processed, and then the results are written into the appropriate cells using .TextMatrix(intRow, intCol) = strData
This works fine. The data is updated flawlessly, and the user can enter his data into the other 3 grids without any problems.
The problem occurs when I want to change the background color of some cells in the top grid.
On rare occasions the received data is very important, and the background color of the corresponding cells should change color.
I change the color of the cells with the following code:
With grd
For lngRow = 1 To .Rows - 1
'default background color
lngBack = vbWhite
'check for important values
If Val(.TextMatrix(lngRow, 1)) >= lngMax Then
'important color
lngBack = &H3040FF
End If
'select whole row
.Row = lngRow
.Col = 0
.RowSel = lngRow
.ColSel = .Cols - 1
'set the background color of the selected row
.CellBackColor = lngBack
Next lngRow
End With 'grd
The problem with this is that when the user is entering data in the other 3 grids, and the background color of a row in the top grid is changed, then the focus moves to the top grid, and the user has to enter his data anew in the grid where he was working.
Is it possible to change the background color of a cell or whole row in a MSFlexGrid without moving the focus to that grid?
So far I could not find a solution to the problem itself.
I created a work around though :
I created an enum containing a value for each grid:
Public Enum ActiveGrid
enuSystem = 0
enuTel = 1
enuRLN = 2
enuRood = 3
enuData = 4
enuCircuit = 5
End Enum
Whenever a grid gets the focus I save the corresponding enum value in a form level variable.
After coloring the required cells in the first grid I return the focus to the grid which last had it.
The user is not editing in the grid itself, but in a textbox which is laid over the cell, so there is no real problem with the grid losing the focus.
When you look closely though you see the focus leave and return quickly.
For now I will accept this work around, and its minor glitches.
Maybe in the future I can come up with a better solution, or anyone else has a better suggestion?

DataGridView: how to make scrollbar in sync with current cell selection?

I have a windows application with DataGridView as data presentation. Every 2 minutes, the grid will be refreshed with new data. In order to keep the scroll bar in sync with the new data added, I have to reset its ScrollBars:
dbv.Rows.Clear(); // clear rows
SCrollBars sc = dbv.ScrollBars;
dbv.ScrollBars = ScrollBars.None;
// continue to populate rows such as dbv.Rows.Add(obj);
dbv.ScrollBars = sc; // restore the scroll bar setting back
With above codes, the scroll bar reappears fine after data refresh. The problem is that the application requires to set certain cell as selected after the refresh:
dbv.CurrentCell = dbv[0, selectedRowIndex];
With above code, the cell is selected; however, the scroll bar's position does not reflect the position of the selected cell's row position. When I try to move the scroll bar after the refresh, the grid will jump to the first row.
It seems that the scroll bar position is set back to 0 after the reset. The code to set grid's CurrentCell does not cause the scroll bar to reposition to the correct place. There is no property or method to get or set scroll bar's value in DataGriadView, as far as I know.
I also tried to set the selected row to the top:
dbv.CurrentCell = dbv[0, selectedRowIndex];
dbv.FirstDisplayedScrollingRowIndex = selectedRowIndex;
The row will be set to the top, but the scroll bar's position is still out of sync. Not sure if there is any way to make scroll bar's position in sync with the selected row which is set in code?
I found an answer to resolve issue. As I mentioned that the control does not have methods or properties to set the correct scroll bar value. However, the scroll bar and the DatagridView content will display correct if there is an interaction directly towards to the UI such as touch the scroll bar or grid cell. It looks like that the control needs to be refocused and a repaint.
Simply use the following codes does not cause the scroll bar reset:
dgv.Select();
// or dbv.Focuse();
The way I found is that I have to make the DatagridView control disappear to back again. Fortunately, I have a tab control with several tabs. Then I switch the tab to get scroll bar reset:
int index = myTabCtrl.SelectedIndex;
if (index == (myTabCtrl.TabCount)) {
dgv.SeletecedIndex = 0;
}
else {
dgv.SelectedIndex = index + 1;
}
myTabCtrl.SelectedIndex = index;
If you don't have any way to hide the DatagridView on your form, you could simply minimize the form and then restore it back.
The problem is that there will be a fresh on the UI.
It seems, TAB, SHIFT+TAB, END keys don't always bring last column into the visible view.
The following code inside the CurrentCellChanged event handler seems to fix this issue (vb.net):
If Me.MyDataGridView.CurrentCell IsNot Nothing Then
Dim currentColumnIndex As Integer = e.MyDataGridView.CurrentCell.ColumnIndex
Dim entireRect As Rectangle = _
Me.MyDataGridView.GetColumnDisplayRectangle(currentColumnIndex, False)
Dim visiblePart As Rectangle = _
Me.MyDataGridView.GetColumnDisplayRectangle(currentColumnIndex, True)
If (visiblePart.Width < entireRect.Width) Or (entireRect.Width = 0) Then
Me.MyDataGridView.FirstDisplayedCell = Me.MyDataGridView.CurrentCell
'OR Me.MyDataGridView.FirstDisplayedScrollingColumnIndex = currentColumnIndex
End If
End If

Resources