Something wrong with this gtk# class for a window? - c#

Learning C#, I feel so guilty for loving it. I'm a microsoft hater. Anyways I'm trying out gtk# and just trying out some simple stuff. I've made a class for the main window and MonoDevelop is complaining about this code, which I swear was just fine a second ago.
public class mwin
{
protected Window win = new Window("test program--");
public mwin()
{
//Configure the parts
win.SetDefaultSize(300,500);
}
public void showWin()
{
win.ShowAll();
}
}
win.SetDefaultSize(300,500);
}--<(here it says "} expected")
But obviously I have a closing brace! Am I missing something?
[edit]
here's whole code. The color stuff was some stuff I was playing around with to color the window, but I didn't finish because the error started. I'm sure it's not the color stuff because it still has an error when I comment them out. http://codepaste.net/b2mwys

You have put your call to "win.SetDefaultSize(300,500);" outside of a method block. The compiler is expecting a closing brace.

Related

while loop prevents other code from executing c#

I'm trying to write a drawing library. In this drawing library there is an update function that should update every frame. I do this by using a do while loop See code below:
private void UpdateCanvas()
{
do
{
Canvas.PumpEvents();
if(UserUpdateVoid != null) UserUpdateVoid();
} while (Canvas.Exists);
}
I also have a function in which the user can set their own update function. This function is part of the SharpDraw class, see code below:
public void SetCustomUpdateFunction(Action function)
{
Console.WriteLine("updated the user function");
UserUpdateVoid = function;
Console.WriteLine(UserUpdateVoid);
}
all this is called in the following way:
public class SharpCanvas
{
private Sdl2Window Canvas;
private GraphicsDevice GraphicsManager;
private Action UserUpdateVoid = null;
public SharpCanvas()
{
WindowCreateInfo WindowInfo = new WindowCreateInfo(
200,
200,
100,
100,
WindowState.Normal,
"SharpWindow"
);
CreateCanvas(WindowInfo);
UpdateCanvas();
}
}
And the SharpDraw instance is made in the following way:
namespace test
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
SharpCanvas Canvas = new SharpCanvas(200,200);
Canvas.SetCustomUpdateFunction(Update);
}
private static void Update(){
Console.WriteLine("update");
}
}
}
But the problem is that the Console.Writelines in the SetCustomUpdateFunction() are never executed. I guess this has to do with the fact that the while loop keeps the program from further execution. So my question is how do i keep the while loop running while still being able to execute different pieces of code? In unity they are able to do it :P
If there is something unclear let me know so i can clarify!
That is entirely normal. It does not mater if you are running a console application, a Windows Form or WPF/UWP application*: Only one piece of code can be executing. While one piece of code does not return, not other code can run.
You need to add some form of Multitasking into the mix. Now that looks extremely like a Console Application and those are the last place I would advise learning Multithreading in. My personal advise is to start under Windows Forms using the BackgroundWorker. It is dated and rarely used in practice, but it can help you get up to speed with the rules and conventions. But this is one area where you can ask 10 people and get 11 Opinions.
*Web Applciations are semi special. As they are pleasingly parallel and it helps with isolation usually each request is given their own Thread. But at least for each singular request, it still holds true.
When you call UpdateCanvas, you enter a loop and code never goes further. To prevent this, you should use threads, async-await or something similar else (see this answer for async-await).
You have to use Multithreading programming. Look for it on google, there are plenty of examples.

Read and Write to the clipboard

I have this snippet on Windows (VS2017 Community) on Unity 5.6:
public static void setClipboardStr(string str)
{
try
{
if (Clipboard.ContainsText())
{
// ...doesn't matter if true or false -
// from here on, I can't copy+paste inside
// the game or outside until I close the app.
// If I had an error instead of try/catch or
// check if it contains text, the error will
// remain UNTIL I REBOOT (beyond the app closing).
}
}
catch(Exception ex)
{
Debug.LogError(ex);
}
}
Whenever I use Clipboard in any form, even when checking if it's text or not, it destroys the clipboard until I close the app. Now, is this a Unity bug? VS bug? Is there something I'm not understanding? What should I use, instead?
Clipboard.ContainsText is from the System.Windows.Forms namespace. These are not supported in Unity. One would be lucky to get it to compile and extremely luck to get work properly since Unity uses Mono. Also, this is not portable so don't use anything from this namespace in Unity.
What should I use, instead?
Write to clipboard:
GUIUtility.systemCopyBuffer = "Hello";
Read from clipboard:
string clipBoard = GUIUtility.systemCopyBuffer;
This should work. If not, you can implement your own clipboard API from scratch using their C++ API. You do have to do this for each platform.

C# Command Line Script Ending Prematurely in Visual Studio

(Sorry if a few parts aren't correct...
I'm a bit of a novice to C# syntax)
I am currently working on a command line project. The project involves creating an algorithm that solves Problem 4 on Project Euler:
https://projecteuler.net/problem=4
From the beginning, ever since I have started the challenges, I've mainly been using Visual Studio to solve them. I've been using a "C# Command Line' type project for the interpretation of information.
Ever since I started using this type of windows form, I've found that as soon as:
static void Main(string[] args)
{
//Insert Code Here...
}
Function finished its events and arguments, it suddenly crashed (well, closed)
I believe that this is because it has and end, it ends itself...
I may be wrong...
In the meantime, I simply used a Thread.Sleep() function as a temporary fix.
How can I solve this problem, and why do you think this is happening?
Thank you!
Try this:
public static void Main(string[] args)
{
try
{
// Your code here
}
catch (Exception ex)
{
// This code will only run if your code fails
Console.WriteLine(ex.ToString()); // Show the exception on the console.
}
Console.ReadKey(); // Make a pause so that the screen does not dissapears when I hit Debug -> Run
}
Try running the project using ctrl + F5 instead of just F5. This is a lot cleaner than adding an unnecessary line to detect keypress at the end of the program IMO

Custom User Control Not Initialized in Auto-Generated Code

This has happened many times before, but I never bothered to figure out why, and now I am tired of it:
For instance, I derive a class from RichTextBox or Panel, I rebuild my project to have the class added to the VS designer toolbox, and then I drag & drop the custom user control to a Form. Everything works fine, and I can run my project...
The problem comes when I edit properties of the Form or the custom user control through the designer. Sometimes, the designer removes the initialization line from its code-behind, causing an exception in the designer and the executable because the control remains uninitialized.
In other words, the following line is removed from say, Form1.Designer.cs:
this.customRichTextBox1=new CustomRichTextBox();
No other line is removed from the code-behind, so the attributes of the custom control are still set, although the variable stays uninitialized.
My solution has always been to manually initialize my user control in the designer code-behind, but the designer eventually removes it again.
I believe that this does not happen when I build a Custom UserControl through the designer (but I am not completely sure of this). It only happens when I define something like the following manually:
class CustomRichTextBox:RichTextBox{}
This is so annoying. What am I doing wrong?
As #Cody requested, here are the steps to reproduce the problem. I am using VS2010, but I've had this problem since 2005, I think.
Step 1. Create new Windows Forms Application, any Framework
Step 2. Add the following class below your main Form class: (It just happens that this is the control that is causing me this problem this time.)
class CustomRichTextBox : RichTextBox
{
Timer tt = new Timer();
internal CustomRichTextBox()
{
tt.Tick += new EventHandler(tt_Tick);
tt.Interval = 200;
}
protected override void OnTextChanged(EventArgs e)
{
tt.Stop();
tt.Start();
}
void tt_Tick(object sender, EventArgs e)
{
System.Diagnostics.Trace.WriteLine("Hello world!");
}
}
Step 3. Press F6 to rebuild.
Step 4. Add the CustomRichTextBox control to your Form by dragging and dropping from the Toolbox.
Step 5. If you wish, you may press F5 to test the application, but it should work. Close the running application.
Step 6. Press F6 to rebuild, and at this point, the designer should crash with the following message: "The variable 'customRichTextBox1' is either undeclared or was never assigned." (In one case, the whole VS completely crashed, but the error is usually contained within the designer.)
Step 7. To correct the issue, go into the code-behind and initialize the variable, but next time you rebuild, the initialization line will be gone.
Thanks to everyone who tried answering my question and who posted comments that helped me diagnose and solve the problem.
The problem occurs when using an "internal" keyword with the control's constructor. Changing it to "public" fixes the problem. The reason for this behavior might be that the Designer's own classes cannot see the constructor because they are not within the namespace of my class unless it is marked public. This all makes sense, and I will use the public keyword from now on.
The class does not need to be in its own individual file or be the first declared class in the file as other answers suggested.
The following class works well because the constructor's keyword was changed to public.
class CustomRichTextBox : RichTextBox
{
Timer tt = new Timer();
public CustomRichTextBox()
{
tt.Tick += new EventHandler(tt_Tick);
tt.Interval = 200;
}
protected override void OnTextChanged(EventArgs e)
{
tt.Stop();
tt.Start();
}
void tt_Tick(object sender, EventArgs e)
{
System.Diagnostics.Trace.WriteLine("Hello world!");
}
}
Is your build set to Debug or it is Release?
I suppose that it is release as I think compiler optimizes the code and remove designer generated line.
Have you tried putting the control code in its own file? I've had problems even with the form designer in the past when the designer code was not int he first class in the file.
I had a similar problem that this posted helped me solve. I have a CustomControl that extends ComboBox, that class contained an internal private class YearItem. I've tried to highlight only the code needed to understand the problem and the solution.
public class YearsCbo : ComboBox //Inherits ComboBox
{
public YearsCbo() {
fill();
}
private void fill() { // <<<=== THIS METHOD ADDED ITEMS TO THE COMBOBOX
for(int idx = 0; idx < 25; idx++) {
this.Items.Add(new YearItem());
}
}
// Other code not shown
private class YearItem {} // <<<=== The VS designer can't access this class and yet
// it generated code to try to do so. That code then fails to compile.
// The compiler error rightfully says it is unable to access
// the private class YearItem
}
I could drag/drop that control YearsCbo onto a form and it worked correctly, but after I returned and edited the form the VS designer generated code that would not compile. The offending code something like this:
Dim YearItem1 As my.ns.YearsCbo.YearItem = New my.ns.YearsCbo.YearItem()
Dim YearItem2 As my.ns.YearsCbo.YearItem = New my.ns.YearsCbo.YearItem()
// This was repeated 25 times because in my constructor I created 25 of these
Me.YearsCbo1.Items.AddRange(New Object() {YearItem1, 2, 3, ..., YearItem25 });
Notice that the designer generated code which tried to access the private class. It didn't need to do that but for some reason it did.
Through trial and error, and this post: How to tell if .NET code is being run by Visual Studio designer came up with a solution:
I added a property to tell if I am running in the designer.
public bool HostedDesignMode
{
get
{
if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
return true;
else
return false;
}
}
I also changed the constructor so that it doesn't call fill() so when the designer runs, there are no items in the ComboBox so the designer doesn't feel the need to manually create those items.
The "fixed" code is shown below:
public class YearsCbo : ComboBox //Inherits ComboBox
{
public YearsCbo() {
if ( ! HostedDesignMode ) {
fill();
}
}
private class YearItem {} // <<<=== Now the VS Designer does not try to access this
}
This code was written using VS2012 Premium on Win7x64 OS (in case it matters).

Trapping messages in .NET

How can i trap a Windows system message (like WM_SETTEXT) that was sent by some window (VLC player window in my case)? I've tried to inherit NativeWindow class and override WndProc like this:
class VLCFilter : NativeWindow
{
System.IntPtr iHandle;
const int WM_SETTEXT = 0x000C;
public VLCFilter()
{
Process p = Process.GetProcessesByName("vlc")[0];
iHandle = p.MainWindowHandle;
}
protected override void WndProc(ref Message aMessage)
{
base.WndProc(ref aMessage);
if (aMessage.HWnd != iHandle)
return false;
if (aMessage.Msg == WM_SETTEXT)
{
MessageBox.Show("VLC window text changed!");
}
}
}
I have checked with Microsoft Spy++ that WM_SETTEXT message is sent by VLC player but my code doesn't seem to get the work done. I've refered mainly to:
http://www.codeproject.com/kb/dotnet/devicevolumemonitor.aspx
I'm trying to make this work for some time with no success. What am I doing wrong? What I am not doing? Maybe there is easier way to do this?
My initial goal is to catch when VLC player (that could be playing somewhere in the background and is not emmbed in my application) repeats its playback (have noticed that WM_SETTEXT message is sent then and I'm trying to find it out like this).
Is your code even being reached? I'm guessing you've inherited from NativeWindow but haven't made your actual windows inherit from your VLCFilter class. Which is in fact going to be a really difficult thing because you'll probably have to rewrite System.Windows.Forms.Form... (I'm guessing there's inheritance in there, but honestly not sure the internal structure in the framework.)
Perhaps you should inherit from Form instead and then have your forms inherit from your new class instead of Form?
I suppose, you could use hook techniques. It's designed for such cases.
Also, this links could be useful, despite they are easiely googled.
http://www.codeproject.com/KB/cs/netwin32hooks.aspx
http://www.codeproject.com/KB/system/WilsonSystemGlobalHooks.aspx
Hello and thanks for Your answers. ;)
Following the: http://www.codeproject.com/KB/system/WilsonSystemGlobalHooks.aspx did the trick and now I'm hooked up to event i wanted. Everything works fine, there's just one glitch: when ovverriding WndProc it starts recieving messages as soon as form is created. Is there a way to temporarily disable WndProc from recieving those messages and enable only when i want to get them?
Do your stuff before the call to the base implementation, else values in Message could have changed.
Somewhere in your code, you should be making a call to NativeWindow.AssignHandle. If you aren't (or if you're passing the wrong handle), then your overridden WndProc won't be called.
Edit: However, because VLC is running in a separate process, this technique won't work. The documentation for the NativeWindow.AssignHandle method states:
Note:
The handle to assign cannot be in a different application process.

Categories

Resources