Results 1 to 7 of 7

Thread: Troubles passing args by ref

  1. #1

    Thread Starter
    Frenzied Member Mike Hildner's Avatar
    Join Date
    Jul 2002
    Location
    Des Moines, NM
    Posts
    1,690

    Troubles passing args by ref

    I've downloaded this code that's in VB.NET - it allows any object to be placed in a status bar panel - button, progress bar etc. I *think* I've converted it to C# ok (it compiles anyway). But now, trying to call a method, I'm running into something I don't know how to fix.

    Here's the code I'm calling:
    Code:
    		public StatusBarChild(ref object obj, ref StatusBar sb, ref Int16 intPanelNumber, Int32 intMargin) 
    		{ 
    			ChildObject = (Control)obj; 
    			StatusBar = sb; 
    			Panel = intPanelNumber; 
    			Margin = intMargin; 
    			ChildObject.Parent = StatusBar; 
    			Resize(); 
    			ChildObject.Visible = true; 
    		}
    Calling with:
    Code:
    sbcProgressBar = new fr.free.marcon.e.StatusBarChild(progressBar1, statusBar1, 1, 2);
    The compiler is complaining about the three args that get passed by ref, for example, "cannot convert from 'System.Windows.Forms.StatusBar to 'ref object''" for the first arg.

    I tried just adding a ref in front of progressBar1, but then another error - "cannot convert from ref ...StatusBar to ref object".

    Can anyone help me out? I might have converted the VB code incorrectly, but not really sure.

    TIA,
    Mike

  2. #2
    Big D Danial's Avatar
    Join Date
    Jul 2000
    Location
    ASP.Net Forum
    Posts
    2,877
    sbcProgressBar = new fr.free.marcon.e.StatusBarChild(progressBar1, statusBar1, 1, 2);


    Your fuction is expecting object as a parameter where as you are passing progress bar.

    try
    Code:
    int i=1;
    
    sbcProgressBar = new fr.free.marcon.e.StatusBarChild(ref (object)progressBar1, ref statusBar1, ref i, 2);
    [VBF RSS Feed]

    There is a great war coming. Are you sure you are on the right side? Atleast I have chosen a side.

    If I have been helpful, Please Rate my Post. Thanks.

    This post was powered by :

  3. #3
    PowerPoster hellswraith's Avatar
    Join Date
    Jul 2002
    Location
    Washington St.
    Posts
    2,464
    also, objects are passed by ref automatically. You don't need to put the ref keyword in for them.

    Also, that code is not optimal.

    Instead of this argument:
    ref object obj

    You should change it to
    ref Control obj

    Then you can get rid of the cast in the first line of the code. What this will do is force you to pass in a control to this method, and if you don't, the compiler will complain before hand. You really can't just pass any ol object into this method, it has to be of a control type.

  4. #4

    Thread Starter
    Frenzied Member Mike Hildner's Avatar
    Join Date
    Jul 2002
    Location
    Des Moines, NM
    Posts
    1,690
    Thanks both for the assistance. I need a little more I'm no expert at C#, as you can probably tell, just trying to understand what's going on here.

    I did what hellswraith suggested and changed from object to Control, that at least made sense to me.
    Code:
    public StatusBarChild(ref Control ctrl, ref StatusBar sb, ref Int16 intPanelNumber, Int32 intMargin) 
    		{ 
    			ChildObject = ctrl; 
    			StatusBar = sb; 
    			Panel = intPanelNumber; 
    			Margin = intMargin; 
    			ChildObject.Parent = StatusBar; 
    			Resize(); 
    			ChildObject.Visible = true; 
    		}
    Now, trying to call this with
    Code:
    fr.free.marcon.e.StatusBarChild sbcProgressBar = new fr.free.marcon.e.StatusBarChild(progressBar1, statusBar1, 1, 2);
    and I get "Argument '1': cannot convert from 'System.Windows.Forms.ProgressBar' to 'ref System.Windows.Forms.Control'
    "

    So I try to cast the ProgressBar into a Control
    Code:
    fr.free.marcon.e.StatusBarChild sbcProgressBar = new fr.free.marcon.e.StatusBarChild((Control)progressBar1, statusBar1, 1, 2);
    and I get "Argument '1': cannot convert from 'System.Windows.Forms.Control' to 'ref System.Windows.Forms.Control'"

    Allright. Object are passed by ref automatically? I don't understand my error then. Even if I try to force ref like this
    Code:
    fr.free.marcon.e.StatusBarChild sbcProgressBar = new fr.free.marcon.e.StatusBarChild(ref (Control)progressBar1, statusBar1, 1, 2);
    Then my error is "A ref or out argument must be an lvalue" - which I think I understand and makes sense, but I just don't get the proper way to call the constuctor.

    I realize this is quite familiar to my first post, but I just wanted to be clear with the steps taken so far.

    Thanks,
    Mike

  5. #5

    Thread Starter
    Frenzied Member Mike Hildner's Avatar
    Join Date
    Jul 2002
    Location
    Des Moines, NM
    Posts
    1,690
    I think I get it now. If I remove the ref in the constructor, there's no need to pass by ref, and there's no need to cast the progress bar into a control - which didn't make sense anyway. That seems to work, anyway.

  6. #6
    PowerPoster hellswraith's Avatar
    Join Date
    Jul 2002
    Location
    Washington St.
    Posts
    2,464
    You all squared away now?

  7. #7

    Thread Starter
    Frenzied Member Mike Hildner's Avatar
    Join Date
    Jul 2002
    Location
    Des Moines, NM
    Posts
    1,690
    Originally posted by hellswraith
    You all squared away now?
    I believe so, and thanks for asking.

    My whole deal here was because I was bent on putting a progress bar inside of status bar panel. Trying to get that rich GUI.

    Searched this forum and found some link to code that did that written in VB.NET. Manually converted to C#, and I think that's where my original problem came from.

    FWIW, here's the code.
    Code:
    // Put ProgressBar in panel [1]
    fr.free.marcon.e.StatusBarChild sbcProgressBar = new fr.free.marcon.e.StatusBarChild(progressBar1, statusBar1, 1, 2);
    .
    .
    .
    using System;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    // Converted the VB author's code to C# 20040902
    // If this works, it was converted by Mike Hildner,
    // if it doesn't, I don't know who did it.
    
    /*
    ' StatusBarChild class
    '
    ' To put any object (a progressbar, a button...) in a statusbar panel in a VB.Net project
    ' E. Marcon, aug. 2004
    ' http://e.marcon.free.fr
    */
    
    namespace fr.free.marcon.e
    {
    	class StatusBarChild
    	{		
    		Control ChildObject;         // The progressbar or any child control
    		StatusBar StatusBar;        // The statusbar
    		Int16 Panel;                // The status panel
    		Int32 Margin;               // The margin between the panel's edge and the progressbar
    
    
    	// API SendMaessageA in User32: returns the rectangle (RECT structure) used to display a status-bar panel
    	[DllImport("user32.dll")]
    	public static extern long SendMessageA(Int32 hwnd, Int32 msg, Int32 wParam, ref RECT lParam);
    	public const long WM_USER = 0x400;
    	//public const long WM_USER = &H400;
    	public const long SB_GETRECT = WM_USER + 10;
    	// RECT structure to get the panel's display rectangle
    	public struct RECT
    	{
    		public Int32 Left;
    		public Int32 Top;
    		public Int32 Right;
    		public Int32 Bottom;
    	}
    
    		//public StatusBarChild(ref Control ctrl, ref StatusBar sb, ref Int16 intPanelNumber, Int32 intMargin)
    		public StatusBarChild(Control ctrl, StatusBar sb, Int16 intPanelNumber, Int32 intMargin) 
    		{ 
    			ChildObject = ctrl; 
    			StatusBar = sb; 
    			Panel = intPanelNumber; 
    			Margin = intMargin; 
    			ChildObject.Parent = StatusBar; 
    			Resize(); 
    			ChildObject.Visible = true; 
    		}
    		
    		public void Resize() 
    		{ 
    			RECT Rectangle = new RECT(); 
    			SendMessageA(StatusBar.Handle.ToInt32(), (int)SB_GETRECT, Panel, ref Rectangle); 
    			ChildObject.Left = Rectangle.Left + Margin; 
    			ChildObject.Top = Rectangle.Top + Margin; 
    			ChildObject.Height = Rectangle.Bottom - Rectangle.Top - 2 * Margin; 
    			ChildObject.Width = Rectangle.Right - Rectangle.Left - 2 * Margin; 
    		}
    	} // end class
    } // end namespace
    
    
    // ======================================
    // Original vb code below
    // ======================================
    
    /*
    ' StatusBarChild class
    '
    ' To put any object (a progressbar, a button...) in a statusbar panel in a VB.Net project
    ' E. Marcon, aug. 2004
    ' http://e.marcon.free.fr
    
    
    Class StatusBarChild
    
        Public ChildObject As Object         ' The progressbar or any child control
        Public StatusBar As StatusBar        ' The statusbar
        Public Panel As Int16                ' The status panel
        Public Margin As Int32               ' The margin between the panel's edge and the progressbar
    
    
        ' API SendMaessageA in User32: returns the rectangle (RECT structure) used to display a status-bar panel
        Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal msg As Int32, ByVal wParam As Int32, ByRef lParam As RECT) As Long
        Public Const WM_USER As Long = &H400
        Public Const SB_GETRECT As Long = (WM_USER + 10)
        ' RECT structure to get the panel's display rectangle
        Public Structure RECT
            Public Left As Int32
            Public Top As Int32
            Public Right As Int32
            Public Bottom As Int32
        End Structure
    
    
        Public Sub New(ByRef obj As Object, ByRef sb As StatusBar, Optional ByRef intPanelNumber As Int16 = 0, Optional ByVal intMargin As Int32 = 2)
            ' Puts a progress bar in a statusbar's panel
    
            ' Affects the progressbar to the class members
            ChildObject = obj
            StatusBar = sb
            Panel = intPanelNumber
            ' Sets the margin between the statusbar panel edge and the progressbar
            Margin = intMargin
            ' Reparent it
            ChildObject.Parent = StatusBar
            ' Set the size
            Resize()
            ' Set it visible
            ChildObject.Visible = True
        End Sub
    
    
        Public Sub Resize()
            'Fits  the child object to the status bar
    
            Dim Rectangle As RECT
            ' Use the API to get the panel's display rectangle
            SendMessage(StatusBar.Handle.ToInt32, SB_GETRECT, Panel, Rectangle)
    
            ' Resize
            With ChildObject
                .Left = Rectangle.Left + Margin
                .Top = Rectangle.Top + Margin
                .Height = Rectangle.Bottom - Rectangle.Top - 2 * Margin
                .Width = Rectangle.Right - Rectangle.Left - 2 * Margin
            End With
        End Sub
    
    End Class
    */

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width