Positioning of a menu item image (hbmpItem of a MENUITEMINFO) in a context menu - vb.net

I am inserting a menu item into an Outlook Context menu for a subject text control. Here you can find a previous question I had on doing this.
The issue I have is that the image of the menu item is positioned strangely in Outlook 2010. In Outlook 2007 it is positioned differently. It seems that the menu item is holding the position for the checked image free in Outlook 2010.
This shows how my menu item looks with the below code. Notice the large space to the left of the image.
This shows how it looks when i add the MIIM_CHECKMARKS flag to fMask and a bitmap to the hbmpUnchecked pointer.
Dim bmp As Drawing.Bitmap = My.Resources.olContextMenuIcon
bmp.MakeTransparent(bmp.GetPixel(10, 10))
hbitmap = bmp.GetHbitmap
Dim mii As New NativeMethodsEX.MENUITEMINFO
With mii
.cbSize = Marshal.SizeOf(mii)
.fMask = NativeMethodsEX.MIIM.MIIM_BITMAP Or NativeMethodsEX.MIIM.MIIM_STRING Or NativeMethodsEX.MIIM.MIIM_FTYPE Or NativeMethodsEX.MIIM.MIIM_STATE Or NativeMethodsEX.MIIM.MIIM_ID
.wID = WM_APP
.fType = NativeMethodsEX.MFT.MFT_STRING
.dwTypeData = String.Concat("Wrong Position")
.fState = NativeMethodsEX.MFS.MFS_ENABLED
.hbmpItem = hbitmap
End With
If ShowTop Then
NativeMethodsEX.InsertMenuItem(aHwnd, 0, True, mii)
NativeMethodsEX.InsertMenu(aHwnd, 1, NativeMethodsEX.MFT.MFT_BYPOSITION Or NativeMethodsEX.MFT.MFT_SEPARATOR, Nothing, Nothing)
Else
Dim menuItemCount As Integer = NativeMethodsEX.GetMenuItemCount(aHwnd)
NativeMethodsEX.InsertMenu(aHwnd, menuItemCount, NativeMethodsEX.MFT.MFT_BYPOSITION Or NativeMethodsEX.MFT.MFT_SEPARATOR, Nothing, Nothing)
NativeMethodsEX.InsertMenuItem(aHwnd, menuItemCount + 1, True, mii)
End If
NativeMethodsEX.DrawMenuBar(subjectRegionHwnd)
So how can I tell the menu item not to reserve the space for the check / uncheck image?

I have two answers to this problem.
I indicated above that the issue existed on an menu in Outlook 2010 but not in Outlook 2007. This is not true. These office versions are of course on different computers and it was a display setting in windows that was the cause of the problem. The above menu is what you get when you have the setting "Use Visual Styles on Windows and buttons" in Performance Options > Visual Effects turned off (Win 7). If you enable this setting then the menus look and especially act very differently.
But what if a user disables this setting how can you deal with it (Not sure if this is relevant for Win10).
You need to set the menu style through the use of the Menuinfo in particular you need to set the flag MNS_NOCHECK. Then the space is gone as the menu no longer is expecting the check marks.
This solution can also be seen here in another stackoverflow answer.

Related

How to change the background color of a windows context menu using the winapi

I am currently trying to customize a context menu in Outlook. For the regulars I have had a series of issues which can be seen in this question and with this question.
I would like to adjust the background color a little.
Dim hBrush As IntPtr = NativeMethodsEX.CreateSolidBrush(ColorTranslator.ToWin32(System.Drawing.Color.Red))
Dim mi As New NativeMethodsEX.MenuInfo
With mi
.cbSize = Marshal.SizeOf(mi)
.fMask = NativeMethodsEX.MIM_STYLE Or NativeMethodsEX.MIM_BACKGROUND Or NativeMethodsEX.MIM_APPLYTOSUBMENUS
.dwStyle = NativeMethodsEX.MNS_NOCHECK
.hbrBack = hBrush
End With
NativeMethodsEX.SetMenuInfo(aHwnd, mi)
This code however produces this;.
How can I also change the background of the left hand side or what even is the class name of that part of the window. Also it has a border as well. What is its class name or how can I either remove it or change it?

Add Image to Custom Task Pane Title in Outlook - VB.Net

I have created a custom task pane in VB.Net for Outlook using the Code given below and I would like to add more content to the header (image and a button) of the User Control instead of just the title. Is there a way I can achieve this?
myUserControl1 = New OutlookTaskPane
myUserControl1.TabStop = True
Dim width As Integer = myUserControl1.Width
myCustomTaskPane = Me.CustomTaskPanes.Add(myUserControl1, "My Custom Task Pane")
myCustomTaskPane.Width = width
myCustomTaskPane.Visible = True
myCustomTaskPane.DockPositionRestrict = Microsoft.Office.Core.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange
Let me know if there is any other way of achieving this please.
Thanks.
Unfortunately the TaskPane header is not customizable. Only Add-in Express supports similar customizations using their implementation of Advanced Form Regions (although only the header icon and header color can be changed and you can't add Windows Forms controls to it). Another option is to implement your own type of Task Pane so you have complete control over the UI; see https://code.msdn.microsoft.com/OlAdjacentWindows/.

Microsoft Visual Studio 2012 using Visual Basic, how to correctly write in code?

Currently I'm new to this and I'm attempting to get this all to work, right now I've looked into and made a module which allows to me to change the user-agent of the internal web-browser so I can manipulate it easily however this is where the issue lies.
I'm assuming I must be editing the auto generated code because the file itself is called "Form1.Designer.vb" and I have no idea where to start putting in custom code to override the current code such as I wanting to do something like this;
Me.WebSiteBrowser1.Dock = System.Windows.Forms.DockStyle.Fill
Me.WebSiteBrowser1.Location = New System.Drawing.Point(3, 3)
Me.WebSiteBrowser1.MinimumSize = New System.Drawing.Size(20, 20)
Me.WebSiteBrowser1.Name = "WebSiteBrowser1"
Me.WebSiteBrowser1.Size = New System.Drawing.Size(671, 413)
Me.WebSiteBrowser1.TabIndex = 0
ChangeUserAgent("This is after the url agent gets changed after the first url open")
Me.WebSiteBrowser1.Navigate("http://www.whatsmyuseragent.com/", Nothing, Nothing, "User-Agent: This is the first open url agent")
However whenever I change anything in the visual template it automatically resets back to
Me.WebSiteBrowser1.Dock = System.Windows.Forms.DockStyle.Fill
Me.WebSiteBrowser1.Location = New System.Drawing.Point(3, 3)
Me.WebSiteBrowser1.MinimumSize = New System.Drawing.Size(20, 20)
Me.WebSiteBrowser1.Name = "WebSiteBrowser1"
Me.WebSiteBrowser1.Size = New System.Drawing.Size(671, 413)
Me.WebSiteBrowser1.TabIndex = 0
So my question is where do I write the custom code that would allow me to keep that after the auto-generation from the visual creator?
You should be putting your code in the form1.vb and leave the designer file alone. In the form1.vb[Design] you can change the properties in the properties window. If it is not currently docked to the right side of the VS designer you can show it by going to the Menu -> View -> Properties Window and select it.

Color constants in Access 2007

The MS Access 2007 Form Design view property sheet exposes some color options that I can't seem to find constants for in order to use them in code. Specifically: Text Dark, Text Light, Background Dark Header and Background Light Header.
Do predefined constants for these exist? I don't seem them in the Object Browser or the Help. Failing that, does anyone know their RGB hex values offhand?
This isn't very well documented at all by Microsoft, so I'll put in a late answer for everyone else who's searching Google for Access Color Constant "Background Light Header".
The best information I've seen is Chris Ward's answer to 'Access system color constants' on the MSDN AccessDev forum, posted on January 1st 2013.
I've reformatted that information into an enumeration:
' Access system color constants, documented by Chris Ward on MSDN Forums, 01-Jan-2013
' https://social.msdn.microsoft.com/Forums/en-US/ccf8b3b7-fa6b-4d05-9883-44b3642e6688/color-themes-decimal-equivelant-documented?forum=accessdev
Public Enum SysColors
acColor_Access_Theme_8 = -2147483600 ' Access Theme 8
acColor_Access_Theme_7 = -2147483601 ' Access Theme 7
acColor_Access_Theme_6 = -2147483602 ' Access Theme 6
acColor_Access_Theme_5 = -2147483603 ' Access Theme 5
acColor_Access_Theme_4 = -2147483604 ' Access Theme 4
acColor_Access_Theme_3 = -2147483605 ' Access Theme 3
acColor_Access_Theme_2 = -2147483606 ' Access Theme 2
acColor_Access_Theme_1 = -2147483607 ' Access Theme 1
acColor_Highlight = -2147483608 ' Highlight
acColor_Borders_Gridlines = -2147483609 ' Borders/Gridlines
acColor_Altenate_Row = -2147483610 ' Altenate Row
acColor_Background_Dark_Header = -2147483611 ' Background Dark Header
acColor_Background_Light_Header = -2147483612 ' Background Light Header
acColor_Background_Form = -2147483613 ' Background Form
acColor_Text_Description = -2147483614 ' Text Description
acColor_Text_Dark = -2147483615 ' Text Dark
acColor_Text_Light = -2147483616 ' Text Light
acColor_Text_Black = -2147483617 ' Text Black
acColor_System_Menu_Bar = -2147483618 ' System Menu Bar
acColor_System_Menu_Highlight = -2147483619 ' System Menu Highlight
acColor_System_Gradient_Inactive_Caption = -2147483620 ' System Gradient Inactive Caption
acColor_System_Gradient_Active_Caption = -2147483621 ' System Gradient Active Caption
acColor_System_Static_Text = -2147483622 ' System Static Text
acColor_System_Static = -2147483623 ' System Static
acColor_System_Tooltip_Background = -2147483624 ' System Tooltip Background
acColor_System_Tooltip_Text = -2147483625 ' System Tooltip Text
acColor_System_3D_Light = -2147483626 ' System 3D Light
acColor_System_3D_Shadow = -2147483627 ' System 3D Shadow
acColor_System_3D_Highlight = -2147483628 ' System 3D Highlight
acColor_System_Inactive_Caption_Light = -2147483629 ' System Inactive Caption Light
acColor_System_Button_Text = -2147483630 ' System Button Text
acColor_System_Alternate_Row = -2147483631 ' System Alternate Row
acColor_System_Button_Shadow = -2147483632 ' System Button Shadow
acColor_System_Button_Face = -2147483633 ' System Button Face
acColor_System_Highlight_Text = -2147483634 ' System Highlight Text
acColor_System_Highlight = -2147483635 ' System Highlight
acColor_System_Application_Background = -2147483636 ' System Application Background
acColor_System_Inactive_Border = -2147483637 ' System Inactive Border
acColor_System_Active_Border = -2147483638 ' System Active Border
acColor_System_Title_Bar_Text = -2147483639 ' System Title Bar Text
acColor_System_Window_Text = -2147483640 ' System Window Text
acColor_System_Menu_Text = -2147483641 ' System Menu Text
acColor_System_Window_Frame = -2147483642 ' System Window Frame
acColor_System_Window = -2147483643 ' System Window
acColor_System_Menu_Background = -2147483644 ' System Menu Background
acColor_System_Inactive_Title_Bar = -2147483645 ' System Inactive Title Bar
acColor_System_Active_Title_Bar = -2147483646 ' System Active Title Bar
acColor_System_Desktop = -2147483647 ' System Desktop
acColor_System_Scrollbar = -2147483648# ' System Scrollbar
End Enum
Note that these aren't numerically-encoded RGB colors: they are addresses to system constants or variables pointing to RGB color definitions which will change if a custom system or application color theme is selected.
This is actually a good thing, as users requiring accessibility settings - high contrast being the most common example - won't be nailed down by your hardcoded color specifications.
You might ask me how to enumerate the lighter and darker tints - 'Text 1, Lighter 50%' and so on - but they aren't actually numeric constants: the 'Lighter' and 'Darker' part of a color descriptor are actually calls to the control's .BackTint and .BackShade methods (for background colors), and the font's Font.TextColor.TintAndShade property (for foreground colors), and you can call those methods from VBA too.
However, I recommend that you open up the help page when you code it up, because the methods for backgrounds and fonts work in slightly different ways, and that inconsistency will catch you out.
I found the answer, the (sort of) hard way. I already have forms with the colors I want set up at design time, so I set breakpoints during their load, and used Debug.Print to find their values. I'll Edit this answer with the values after I play around a bit and make sure I'm not mixing up which is which.
In the meantime, I'm going to Accept Beth's answer, since it got me thinking in the direction that led to the solution.
Edit
Here are the values for the four that I asked about originally, in context:
Public Sub SetHeader(frm As Form)
On Error GoTo Error_Handler
'Access-specific Theme colors
Const TextLight As Long = -2147483616
Const TextDark As Long = -2147483615
Const BackLight As Long = -2147483612
Const BackDark As Long = -2147483611
With frm
If gblnAuthorized Then
.FormHeader.BackColor = BackLight
!Auto_Title0.ForeColor = TextDark
Else
.FormHeader.BackColor = BackDark
!Auto_Title0.ForeColor = TextLight
End If
End With
Exit_Procedure:
Exit Sub
Error_Handler:
DisplayUnexpectedError Err.Number, Err.Description
Resume Exit_Procedure
Resume
End Sub
Edit 2
Just by accident, I found an easier way to find the values for these. Go into the VB Editor and open the form's code. Select the control in the drop down at the top of the Propeties window and read the BackColor (or whatever) from there--it's in the same decimal format I used in the code above, rather than the name used in the Acces design environment. Edit 3 The form has to be open in Design or Layout view in the main Access environment for this to work.
They may come from Windows system settings and not correspond to the same RGB value on every computer.
After finding this
You can also see in the Back Color property (or, for that matter, any color property) a list of 20 additional options. These include Alternate Row, Background Form, Background Light Header, Background Dark Header, Borders/Gridlines, Text Black, Text Description, Text Light, Text Dark, Highlight, and Access Theme 1, Access Theme 2, and so on, up to Access Theme 10. These are shades of the color scheme you chose in Access Options-shades of blue for the Blue or Silver theme, and shades of gray and black for the Black theme, and with a shade of orange in all themes for Highlight.
here
I'm now thinking it's local to Access.
It may be something you can't do with a single RGB value.
VBA Constant Description
vbScrollBars Scrollbar color
vbDesktop Desktop color
vbActiveTitleBar Color of the title bar for the active window
vbInactiveTitleBar Color of the title bar for the inactive window
vbMenuBar Menu background color
vbWindowBackground Window background color
vbWindowFrame Window frame color
vbMenuText Color of text on menus
vbWindowText Color of text in windows
vbTitleBarText Color of text in caption, size box, and scroll arrow
vbActiveBorder Border color of active window
vbInactiveBorder Border color of inactive window
vbApplicationWorkspace Background color of multiple document interface applications
vbHighlight Background color of items selected in a control
vbHighlightText Text color of items selected in a control
vbButtonFace Color of shading on the face of command buttons
vbButtonShadow Color of shading on the edge of command buttons
vbGrayText Grayed (disabled) text
vbButtonText Text color on push buttons
vbInactiveCaptionText Color of text in an inactive caption
vb3DHighlight Highlight color for 3-D display elements
vb3DDKShadow Darkest shadow color for 3-D display elements
vb3DLight Second lightest 3-D color after vb3DHighlight
vbInfoText Color of text in ToolTips
vbInfoBackground Background color of ToolTips

Windows Forms: Unable to Click to Focus a MaskedTextBox in a Non TopLevel Form

Like the title says, I've got a Child form being shown with it's TopLevel property set to False and I am unable to click a MaskedTextBox control that it contains (in order to bring focus to it). I can bring focus to it by using TAB on the keyboard though.
The child form contains other regular TextBox controls and these I can click to focus with no problems, although they also exhibit some odd behavior: for example if I've got a value in the Textbox and I try to drag-click from the end of the string to the beginning, nothing happens. In fact I can't use my mouse to move the cursor inside the TextBox's text at all (although they keyboard arrow keys work).
I'm not too worried about the odd TextBox behavior, but why can't I activate my MaskedTextBox by clicking on it?
Below is the code that shows the form:
Dim newReportForm As New Form
Dim formName As String
Dim FullTypeName As String
Dim FormInstanceType As Type
formName = TreeView1.SelectedNode.Name
FullTypeName = Application.ProductName & "." & formName
FormInstanceType = Type.GetType(FullTypeName, True, True)
newReportForm = CType(Activator.CreateInstance(FormInstanceType), Form)
Try
newReportForm.Top = CType(SplitContainer1.Panel2.Controls(0), Form).Top + 25
newReportForm.Left = CType(SplitContainer1.Panel2.Controls(0), Form).Left + 25
Catch
End Try
newReportForm.TopLevel = False
newReportForm.Parent = SplitContainer1.Panel2
newReportForm.BringToFront()
newReportForm.Show()
I tried your code and got a good repro this time. As I mentioned in my original post, this is indeed a window activation problem. You can see this in Spy++, note the WM_MOUSEACTIVATE messages.
This happens because you display the form with a caption bar. That convinces the Windows window manager that the window can be activated. That doesn't actually work, it is no longer a top-level window. Visible from the caption bar, it never gets drawn with the "window activated" colors.
You will have to remove the caption bar from the form. That's best done by adding this line to your code:
newReportForm.FormBorderStyle = Windows.Forms.FormBorderStyle.None
Which will turn the form into a control that's otherwise indistinguishable from a UserControl. You can still make it distinctive by using this code instead:
newReportForm.ControlBox = False
newReportForm.Text = ""
Either fix solves the mouse click problem.
This is a miserable bug and it took me a long time to find this question. We're doing exactly the same thing as the OP, displaying a Form inside a split container. My workaround was to add an event handler to the MaskedTextBox's Click event:
private void MaskedTextBoxSetFocus(object sender, EventArgs e)
{
var mtb = (MaskedTextBox)sender;
mtb.Focus();
}
This works for the MaskedTextBox but I'm concerned about other odd behavior due to this bug so I will probably set the border style as in the accepted answer.
The text box behavior is a symptom of the same problem. Something is swallowing mouse down notifications. It isn't explained by your code snippet. Forms indeed swallow the mouse click that activates them, but that is a one-time behavior and is turned off by setting its TopLevel property to False.
Not much left. One candidate is the Control.Capture property, turned on at the MouseDown event for a button so that the button can see the MouseUp event, no matter where the mouse moved. That's a one-time effect as well. Watch out for controls that set the Focus in a MouseDown event.
The other is some kind of IMessageFilter code in your form(s) that's eating WM_LBUTTONDOWN messages.