prasannavl / WinApi

A simple, direct, ultra-thin CLR library for high-performance Win32 Native Interop

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Create Button doesn't work ?

malickf opened this issue · comments

I'm trying to create a button using the function Button create method (

public static Button Create(string text = null,
)

However it doesn't work and I can't find an unit test or an example using this code.

I would like to add a button to a native winform (of another application).

To get handle of this external window I use :

IntPtr hdl = (IntPtr)0x00020E06;
WinApi.Windows.NativeWindow  win = WinApi.Windows.WindowFactory.CreateWindowFromHandle(hdl); 

Then to add a button to this window :

 WinApi.Windows.Controls.Button.ButtonStyles styleb = WinApi.Windows.Controls.Button.ButtonStyles.BS_DEFPUSHBUTTON;

WinApi.Windows.Controls.Button.Create("Test",controlStyles: styleb, styles:   WinApi.User32.WindowStyles.WS_CHILD | WinApi.User32.WindowStyles.WS_VISIBLE, exStyles:0,hParent :win.Handle, width:150,height:100, x:20,y:20);

This doesn't work, no button is added to the window and the window freezes...

Should I create the button in a new thread ? or could you provide an example ?

Thanks

I have added User32Methods.UpdateWindow(win.Handle); at the end and now I can see the button that is effectively added to the winform.

However the winform is still frozen.... any idea why ?
Thanks

There are numerous samples provided in the samples directory. The https://github.com/prasannavl/WinApi/tree/master/Samples/Sample.SimulateInput should likely help.

I seem to get the feeling that you somehow aren't running the message loop properly. Please provide the full sample, if you'd like me to check it out.

However the winform is still frozen.... any idea why ?

Also, I'm afraid if you aren't familiar with Win32 programming, you probably might want to look for a higher level library. This library intends to make raw Win32 programming much easier with C# - not to use with WinForms. I hope I'm wrong, but I get the feeling that you're mixing and matching things without really understanding how WinForms and Win32 are layered.

And there are no specific samples for WinApi.Windows.Controls - because, as mentioned in the docs don't intent to support that scenario at all. That package is a sample by itself - to provide an idea on how to write GDI controls, if at all you need it.

Edit: now that I look at it, I only mentioned that I don't intend to support Controls scenario here: https://www.prasannavl.com/2016/10/introducing-winapi-comparing-gc-pressure-and-performance-with-winforms/ in the last paragraph. But never in the docs. Thanks for leading up to it - will add it to the docs.

Thanks for your quick answer, I ll try again, study more your example and come back to you after that.

I do need to use raw Win32 programming as I need to extend a native form of another application ( not a .Net one but a C++ one). Basically I'm trying to achieve the same as described here (https://www.codeproject.com/Articles/790966/Hosting-And-Changing-Controls-In-Other-Application ) but with your library , (ie: add my own control on top of another application ).

ps: in my aforementioned example I have obtained the handle of the parent window via Window Detective ( similar to Spy++)

Edit : thanks for your information about Controls

You point me in the correct direction with your example.
I have succeed, and I'm impressed: it is in fact very easy with your library , full code :

static int Main(string[] args)
{
        IntPtr hdl = (IntPtr)0x000E0A08;
        try
        {
                WinApi.Windows.Controls.Button.ButtonStyles styleb = WinApi.Windows.Controls.Button.ButtonStyles.BS_DEFPUSHBUTTON;
                using (var bounton = WinApi.Windows.Controls.Button.Create("Test", controlStyles: styleb, styles: WinApi.User32.WindowStyles.WS_CHILD | WinApi.User32.WindowStyles.WS_VISIBLE, hParent: hdl, width: 150, height: 100, x: 120, y: 120))
                {
                    bounton.Show();
                    return new EventLoop().Run(bounton);
                }
        }
        catch (Exception ex)
        {
        Console.WriteLine(ex.Message);
        }
       return 0;
}

Many thanks !

Ah. I see what you're trying to do. You don't have a message loop for your Button. That why it appears frozen. I roughly glanced over the article you sent, and it mentions Win32Button - but Windows Forms is not exactly it's C/C++ equivalent - It often does a lot more. If you look at the Win32Button constructor, you'll see that it runs it's own message loop in a new thread.

But this is a raw library. It's upto you to run a message loop - Basically - if you know how you'll write the C/C++ version of the code, then you write the WinApi.Windows the exact same way - just with some C# goodness and a lot of sugar. But procedurally it's exactly the same as how you'd write your C/C++ code.

Well, seems you beat me to it :) Glad it worked out.

Yes, you are correct my error is that I was missing the message loop. Thanks again.

ps : In the link I have posted the Win32Button is not from System.Forms but it is given in the src code of the article and it does run a message loop as you said.

Thanks for the correction - I mixed it up in a hurry. Sorry about that. Cheers!