Calling Form2 from Form1 in VB6 using instances problem - c#

Actually I wanted to use cefsharp with my VB6 project and I am having following two problems:-
My project runs from let's say form1 and I need to call form2 where I have initialized the chromium browser using cefsharp by making use of C# class library.
Now when I call form2 from form1 like
form2.showme
(Where showme is just a custom function to set size etc) the chromium browser is able to get initialized without any issues, but when I call form2 like
Public ofrm2 AS form2
Public Sub function()
Set ofrm2=new form2
call ofrm2.showme
End Sub
then even though no error log or error of any kind is given and form2 is shown successfully, but there is no cefsharp chromium browser object on it this time.
I am also using SetParent and SetWindowPos to set up the length and width of my chromium browser in form2. I really am unable to find the issue, please suggest some fix.
The second problem is VB6 Editor does not allow debugging as soon as my code Initializes chromium. The only way to test the application for me was to make an exe and then run the application and try debugging using logs.
Edit:- ****************************************************************
My C# dll containing cefsharp packages
[PermissionSet(SecurityAction.Demand, Name ="FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
[ClassInterface(ClassInterfaceType.None)]
public partial class Form1 : Form, IForm1
{
private ChromiumWebBrowser _browser;
public Form1()
{
InitializeComponent();
//initializeChromium();
}
public int initializeChromium()
{
CefSettings settings = new CefSettings();
if (!Cef.IsInitialized)
{
CefSharp.Cef.Initialize(settings);
}
_browser = new ChromiumWebBrowser("http://127.0.0.1:24125/ABC/DEF.html");
_browser.RegisterJsObject("External", this);
this.Controls.Add(_browser);
_browser.BringToFront();
_browser.Dock = DockStyle.Fill;
this.Show();
return 0;
}
}
My Form1:-
Private Sub Form_Load()
Call launch ------ This one does not work. definition is given in my module below
'frmHTML.Show -----This one works
End Sub
Private Sub Form_UnLoad(cancel As Integer)
Set ofrmHtml = Nothing
End Sub
ModDec.bas:-
Option Explicit
Public Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Public Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public ofrmHtml As frmHTML
Public Sub launch()
Set ofrmHtml = New frmHTML
Call ofrmHtml.InitChromium1
ofrmHtml.ShowMe
'call ofrmHtml.ShowMe
End Sub
My form2(frmHTML):-
Option Explicit
Public cSharpObj As New cSharp.Form1
Private Sub Form_Load()
'Call InitChromium1
Exit Sub
End Sub
Public Sub InitChromium1()
' On Error GoTo Err_Hndlr
SetParent cSharpObj.getHandle, frmHTML.hWnd
SetWindowPos cSharpObj.getHandle, 0, 0, 0, 512, 480, 0
Dim i As Integer
i = -1
i = cSharpObj.initializeChromium()
Exit Sub
End Sub
Public Sub ShowMe()
Call Me.Show
End Sub

Related

MessageBox Top Most True

is there way to make the default messagebox ( MessageBox.Show() ) TopMost true which also stays on top even if the messagebox lost the focus?
I don't want to create a custom one.
Is there a way doing it by using SetWindowHook or something similar?
I already researched a lot but all solutions I found were not working.
Can someone help me out how to do this in VB.net or C#?
The simplest way is to p/invoke the MessageBox function and pass the MB_SYSTEMMODAL flag.
I got it.
This will show a messagebox on top of all windows opened, doesn't matter if they have Topmost options or not, the messagebox appears always in front.
Public Enum MessageBoxResult As UInteger
Ok = 1
Cancel
Abort
Retry
Ignore
Yes
No
Close
Help
TryAgain
ContinueOn
Timeout = 32000
End Enum
Public Enum MessageBoxOptions As UInteger
SystemModal = &H1000
NoFocus = &H8000
SetForeground = &H10000
Topmost = &H40000
End Enum
<DllImport("user32.dll", EntryPoint:="MessageBoxW", SetLastError:=True, Charset:=CharSet.Unicode)> _
Public Shared Function MessageBox(hwnd As IntPtr, _
<MarshalAs(UnmanagedType.LPTStr)> lpText As String, _
<MarshalAs(UnmanagedType.LPTStr)> lpCaption As String, _
<MarshalAs(UnmanagedType.U4)> uType As MessageBoxOptions) As <MarshalAs(UnmanagedType.U4)> MessageBoxResult
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
MessageBox(IntPtr.Zero, TextBox2.Text, TextBox1.Text, MessageBoxButtons.OK Or MessageBoxOptions.SystemModal + MessageBoxOptions.Topmost + MessageBoxOptions.SetForeground + MessageBoxIcon.Information)
End Sub
End Class

i want to get live stream from an ip cam.. and after that i want pictures from that live stream....in vb.net

Imports AForge.Video
Imports AForge.Video.VFW
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
Dim Stream As AForge.Video.MJPEGStream = New AForge.Video.MJPEGStream("http://192.168.1.250/mjpeg.cgi")
Stream.Login = ("admin")
Stream.Password = ("admin")
Stream.Start()
Dim st As String = ""
Catch ex As Exception
MsgBox(ex.Message.ToString(), MsgBoxStyle.OkOnly, "Error")
Exit Sub
End Try
End Sub
End Class
this is what i have done so far....to get stream started...
know i want know.
how can i show this stream in picture box? and how to get images from this stream.
The MJEGStream includes events. Declare your Stream object on class level as
Private WithEvents Stream As AForge.Video.MJPEGStream
Then add an event handler to the MJPEGStream.NewFrame event with a sub like
Private Sub Handle_NewFrame(sender as Object, e as AForge.Video.NewFrameEventArgs)
Picturebox1.Image = e.Frame
End Sub
Start the stream like you have done in your code.
Don't forget to initialize the Source object.
Source = New AForge.Video.MJPEGStream("http://192.168.1.250/mjpeg.cgi")
The eventargs variable contains the new frame as an image that you can then display in a picturebox.
It's been a while since I have worked with AForge, but it should be ok.

Help with GDI+ interop in .Net

I'm using some code to enable me to render rotated text with the TextRenderer.DrawText method. (By default, DrawText can only copy a straight forward x and y transform from a graphics object).
The code (C#) is from: connect.microsoft.com. See below for a VB conversion.
The code takes a graphics object, creates a device context and copies the transform matrix from the graphics object. It works, but I'd like, also, to set the TextRenderingHint, so I tried:
<DllImport("gdiplus.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)> _
Public Shared Function GdipSetTextRenderingHint(ByVal graphics As HandleRef, ByVal textRenderingHint As System.Drawing.Text.TextRenderingHint) As Integer
End Function
And then after the SetClip statement, I place: GdipSetTextRenderingHint(hDC, someHint)
This gives me a memory access violation error, so I think I should be using something other than hDC as the argument.
I can get it to work by creating the device context from the original graphics object, and then creating another graphics object from the device context. I then set the hint on the new graphics object. This seems a bit convoluted so I was wondering if it was possible through interop.
VB.Net code conversion:
Friend Class TextRendererDC
Implements IDeviceContext
Implements IDisposable
Private graphics As Graphics
Private dc As IntPtr
Private Sub New()
End Sub
Public Sub New(ByVal g As Graphics)
Me.graphics = g
End Sub
Public Function GetHdc() As IntPtr Implements System.Drawing.IDeviceContext.GetHdc
Dim xform As NativeMethods.XFORM
Dim clipRgn As IntPtr
Using transf As Matrix = Me.graphics.Transform
xform = New NativeMethods.XFORM(transf)
End Using
Using clip As Region = Me.graphics.Clip
clipRgn = clip.GetHrgn(Me.graphics)
End Using
Me.dc = Me.graphics.GetHdc()
Dim hDC As New HandleRef(Me, Me.dc)
Dim hRegion As New HandleRef(Nothing, clipRgn)
SetTransform(hDC, xform)
SetClip(hDC, hRegion)
// The below call creates a memory access violation.
NativeMethods.GdipSetTextRenderingHint(hDC, System.Drawing.Text.TextRenderingHint.AntiAliasGridFit)
Return Me.dc
End Function
Public Sub ReleaseHdc() Implements System.Drawing.IDeviceContext.ReleaseHdc
If Me.dc <> IntPtr.Zero Then
Me.graphics.ReleaseHdc()
Me.dc = IntPtr.Zero
End If
End Sub
Public Sub Dispose() Implements System.IDisposable.Dispose
ReleaseHdc()
End Sub
Private Shared Sub SetTransform(ByVal hdc As HandleRef, ByVal xform As NativeMethods.XFORM)
NativeMethods.SetGraphicsMode(hdc, NativeMethods.GM_ADVANCED)
NativeMethods.SetWorldTransform(hdc, xform)
End Sub
Private Shared Sub SetClip(ByVal hdc As HandleRef, ByVal hRegion As HandleRef)
NativeMethods.SelectClipRgn(hdc, hRegion)
End Sub
Private Class NativeMethods
Public Const GM_ADVANCED As Integer = 2
<DllImport("Gdi32")> _
Public Shared Function SetGraphicsMode(ByVal hdc As HandleRef, ByVal mode As Integer) As Integer
End Function
<DllImport("Gdi32")> _
Public Shared Function SetWorldTransform(ByVal hDC As HandleRef, ByVal xform As NativeMethods.XFORM) As Boolean
End Function
<DllImport("Gdi32")> _
Public Shared Function SelectClipRgn(ByVal hDC As HandleRef, ByVal hRgn As HandleRef) As Integer
End Function
<DllImport("gdiplus.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)> _
Public Shared Function GdipSetTextRenderingHint(ByVal graphics As HandleRef, ByVal textRenderingHint As System.Drawing.Text.TextRenderingHint) As Integer
End Function
<StructLayout(LayoutKind.Sequential)> _
Public Class XFORM
Public eM11 As Single
Public eM12 As Single
Public eM21 As Single
Public eM22 As Single
Public eDx As Single
Public eDy As Single
Public Sub New()
Me.eM11 = 1.0!
Me.eM22 = 1.0!
End Sub
Public Sub New(ByVal transform As Matrix)
Me.eM11 = 1.0!
Me.eM22 = 1.0!
Me.eM11 = transform.Elements(0)
Me.eM12 = transform.Elements(1)
Me.eM21 = transform.Elements(2)
Me.eM22 = transform.Elements(3)
Me.eDx = transform.Elements(4)
Me.eDy = transform.Elements(5)
End Sub
End Class
End Class
End Class
Wow, that fits the "a little knowledge could be dangerous" mold. Not even the native C++ programmers call the gdiplus entry point directly, they use the C++ wrapper in <gdiplus.h>
The failure mode here is that your program is loading the wrong version of gdiplus.dll, the one in c:\windows\system32. The legacy version. The right one is in the Windows side-by-side cache, .NET's System.Drawing assembly contains code to make sure it gets the right version of the DLL from the cache.
Not the one you get. Yours isn't even initialized, GdiplusStartup was never called. Kaboom.
No clue what you're trying to accomplish. The Graphics class has a TextRenderingHint property, no need for the killer poke.

Why is this .net UIAutomation app leaking/pooling?

I've got an app using .net UIAutomation, it eventually runs out of memory and crashes just monitoring windows being shown and closed. Seemed easier to show this in VB than C# but happens the same either way. It appears to be a leak/pool in the underlying proxy objects. Most of the memory is not being shown as in use as .net memory.
Any ideas on how to get this to stop leaking and still monitor StructureChangedEvents?
Imports System.Windows.Automation
Public Class Form1
Delegate Sub AddListCallback(ByVal Text As String)
Dim UIAeventHandler As StructureChangedEventHandler
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
BtnStartStop.Text = "Stop"
Subscribe()
End Sub
Private Sub BtnStartStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStartStop.Click
If "Start" = BtnStartStop.Text Then
BtnStartStop.Text = "Stop"
Subscribe()
Else
BtnStartStop.Text = "Start"
Unsubscribe()
lbEvents.Items.Clear()
GC.GetTotalMemory(True)
End If
End Sub
Public Sub Subscribe()
UIAeventHandler = New StructureChangedEventHandler(AddressOf OnUIAutomationEvent)
Automation.AddStructureChangedEventHandler(AutomationElement.RootElement, TreeScope.Descendants, UIAeventHandler)
End Sub
Public Sub Unsubscribe()
Automation.RemoveStructureChangedEventHandler(AutomationElement.RootElement, UIAeventHandler)
End Sub
''' <summary>
''' AutomationEventHandler delegate.
''' </summary>
''' <param name="src">Object that raised the event.</param>
''' <param name="e">Event arguments.</param>
Private Sub OnUIAutomationEvent(ByVal src As Object, ByVal e As StructureChangedEventArgs)
' Make sure the element still exists. Elements such as tooltips can disappear
' before the event is processed.
If e.StructureChangeType = StructureChangeType.ChildrenInvalidated Then
Exit Sub
End If
Dim sourceElement As AutomationElement
Try
sourceElement = DirectCast(src, AutomationElement)
Catch ex As ElementNotAvailableException
Exit Sub
End Try
' TODO Handle any other events that have been subscribed to.
Console.WriteLine( "Element : """ & sourceElement.Current.LocalizedControlType & """ """ & sourceElement.Current.Name _
& """ Struct Change Type : " & [Enum].GetName(GetType(StructureChangeType), e.StructureChangeType) _
& " Runtime ID : " & getString(e.GetRuntimeId()))
End Sub
Private Function getString(ByVal ints As Integer()) As String
getString = ""
For Each i As Integer In ints
getString = getString & " " & i.ToString
Next
End Function
End Class
I would do something like this when you unsubscribe:
Automation.RemoveAllEventHandlers();
UIAeventHandler = null;
UIAutomation will keep some threads alive as long as you've got an AutomationEventHandler object around. Its pretty much a black box to me, but the above has fixed all issues that I had.
#jaws is correct (there are some additional things to think about), but it is in C#. for VB you need to do the following:
Automation.RemoveStructureChangedEventHandler(AutomationElement.RootElement, UIAeventHandler)
UIAeventHandler = Nothing
Because you do not set the UIAeventHandler to nothing, when you unsubscribe then, you are re-assigning the event handler which is already in memory.
To think about. Notice that you are calling subscribe when the form loads and subscribe/unsubscribe with a button. When the form loads then, the event handler is assigned and should work fine, that is until you hit unsubscribe/subscribe (in that order). When you did not set the UIAeventHandler to Nothing then, you are causing a memory leak because you then set the UIAeventHandler to a NEW instance on subscribe. Therefore, you could also do the following as suggested by #jaws :
Imports System.Windows.Automation
Public Class Form1
Dim UIAeventHandler as StructureChangedEventHandler
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
BtnStartStop.Text = "Stop"
Subscribe()
End Sub
Public Sub Subscribe()
UIAeventHandler = New StructureChangedEventHandler(AddressOf OnUIAutomationEvent)
Automation.AddStructureChangedEventHandler(AutomationElement.RootElement, TreeScope.Descendants, UIAeventHandler)
End Sub
Public Sub Unsubscribe()
Automation.RemoveStructureChangedEventHandler(AutomationElement.RootElement, UIAeventHandler)
UIAeventHandler = Nothing 'Here is the Important part!
End Sub
End Class

My tray icon stops responding when my app is minimized!

After finding this question and following the instructions there, plus following many of the links, I managed to get my app to appear as a system tray icon, and it disappears from the task bar when I minimize it.
BUT - weird behavior! When the form is open, the system tray icon works fine. But as soon as I minimize it, the tray icon stops responding to any kind of mouse click.
Other facts that may come into play: the form is started up by a thread spun off from the main thread, and it is opened with .ShowDialog(). There are also several other threads running in the background.
Any ideas what's going wrong?
Replace f.ShowDialog(); with Application.Run(f); where f is the variable holding your Form and it should work fine. The problem is that ShowDialog returns (and it's message loop ends) when you hide the form. Application.Run provides a proper message loop and your window works after it has been hidden and can be show again using the system tray icon.
Not too sure what your code looks like, but below is some code I pulled from one of our apps. Its written in VB but should not be too hard for you to convert. The key is to create an ApplicationContext class to host your code. This code has no problems showing a form and then closing it repeatedly or with minimizing or maximizing.
Public Class NotifyApplicationContext
Inherits ApplicationContext
Private components As System.ComponentModel.IContainer
Private Notify As System.Windows.Forms.NotifyIcon
Private Menu As System.Windows.Forms.ContextMenu
Private mnuForm As System.Windows.Forms.MenuItem
Private F As Form
Public Sub New()
InitializeContext()
End Sub
Private Sub InitializeContext()
Me.components = New System.ComponentModel.Container
Me.Notify = New System.Windows.Forms.NotifyIcon(Me.components)
SetupContextMenu()
Notify.ContextMenu = Me.Menu
Notify.Icon = New Icon("YourApplicationIcon", 16, 16)
Notify.Text = "Your Application Text"
Notify.Visible = True
F = New Form
F.Show()
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
MyBase.Dispose(disposing)
End Sub
Protected Overrides Sub ExitThreadCore()
MyBase.ExitThreadCore()
End Sub
Private Sub SetupContextMenu()
Me.Menu = New System.Windows.Forms.ContextMenu
Me.mnuForm = New System.Windows.Forms.MenuItem
Me.Menu.MenuItems.Add(mnuForm)
mnuForm.Index = 7
mnuForm.Text = "FormText"
AddHandler mnuForm.Click, AddressOf Me.mnuTemp_Click
End Sub
Private Sub mnuForm_Click(ByVal sender As Object, ByVal e As System.EventArgs)
If F IsNot Nothing Then
If F.Visible = True Then
F.Close()
F.Dispose()
F = Nothing
End If
Else
F = New Form
F.Show()
End If
Notify.Text = "Change Application Text Here"
End Sub
End Class
Public Class Startup
<STAThread()> _
Public Shared Sub Main()
Dim N As ApplicationContext = New NotifyApplicationContext
Application.Run(N)
End Sub
End Class

Categories

Resources