C# windows forms application volume slider - c#

I have an application that plays a .wav file using the soundplayer, I looked it up and couldn't find a way to change the volume it plays in. What I'm looking for is either to change the volume of the file independently through the program or have a slider to change the volume of the window itself in windows volume mixer. Thanks!
public void loadSound()
{
sp.Load();
sp.Play();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (BarTimer.Value < BarTimer.Maximum)
{
BarTimer.Value = BarTimer.Value + 1;
}
if(BarTimer.Value==BarTimer.Maximum)
{
loadSound();
timer1.Stop();
BarTimer.Value = BarTimer.Minimum;
}
}

I only found this on MSDN: Attenuating SoundPlayer Volume.
It uses waveOutGetVolume and waveOutSetVolume functiuons.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace VolumeControl
{
public partial class Form1 : Form
{
[DllImport("winmm.dll")]
public static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);
[DllImport("winmm.dll")]
public static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);
public Form1()
{
InitializeComponent();
// By the default set the volume to 0
uint CurrVol = 0;
// At this point, CurrVol gets assigned the volume
waveOutGetVolume(IntPtr.Zero, out CurrVol);
// Calculate the volume
ushort CalcVol = (ushort)(CurrVol & 0x0000ffff);
// Get the volume on a scale of 1 to 10 (to fit the trackbar)
trackWave.Value = CalcVol / (ushort.MaxValue / 10);
}
private void trackWave_Scroll(object sender, EventArgs e)
{
// Calculate the volume that's being set. BTW: this is a trackbar!
int NewVolume = ((ushort.MaxValue / 10) * trackWave.Value);
// Set the same volume for both the left and the right channels
uint NewVolumeAllChannels = (((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16));
// Set the volume
waveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
}
}
}
Hope it helped.

Related

use c++ function that returns Mat in c# and convert it to bitmap

i've written a function in c++ and the function returns a Mat.then I build a dll file from c++ file and use the function in c# windows application.I guess because it doesn't get converted to Bitmap the picturebox doesn't show anything and it is still empty.
here is the c++ code:
#define MyFunctions _declspec(dllexport)
#include "opencv2/core.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "iostream"
#include "stdio.h"
using namespace cv;
using namespace std;
extern "C" {
MyFunctions Mat getFrame()
{
Mat frame;
//--- INITIALIZE VIDEOCAPTURE
VideoCapture cap;
// open the default camera using default API
// cap.open(0);
// OR advance usage: select any API backend
int deviceID = 0; // 0 = open default camera
int apiID = cv::CAP_ANY; // 0 = autodetect default API
// open selected camera using selected API
cap.open(deviceID, apiID);
// check if we succeeded
if (!cap.isOpened()) {
cerr << "ERROR! Unable to open camera\n";
}
//--- GRAB AND WRITE LOOP
cout << "Start grabbing" << endl
<< "Press any key to terminate" << endl;
// wait for a new frame from camera and store it into 'frame'
for (int i = 0; i<10; i++)
{
// wait for a new frame from camera and store it into 'frame'
cap.read(frame);
// check if we succeeded
if (frame.empty()) {
cerr << "ERROR! blank frame grabbed\n";
break;
}
// show live and wait for a key with timeout long enough to show images
imshow("Live", frame);
if (waitKey(5) >= 0)
break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return frame;
}
}
and here is the c# code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.Util;
using System.Drawing.Imaging;
namespace MyForm
{
public partial class Form1 : Form
{
public const string CppFunctionsDLL = #"..\..\..\x64\Debug\cpp.dll";
[DllImport(CppFunctionsDLL, CallingConvention = CallingConvention.Cdecl)]
public static extern Mat getFrame();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Mat mat = new Mat();
mat = getFrame();
Image<Bgr, byte> image = mat.ToImage<Bgr, byte>();
Bitmap bm = image.ToBitmap();
pictureBox1.Image = bm;
}
}
}
any solutions on how to get it to be shown on picturebox?
thank you in advance.

Autoclicker Visual studio CS

I tried to make my own autoclicker. Everything went fine.
But when i press the button it only changes status from off to on.. but nothing happens.
I tried very long time to check for errors but i didnt find any.
This is my script so if you find any errors please tell me!
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace BetaClicker
{
public partial class form1 : Form
{
[DllImport(dllName:"user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
private const int LEFTUP = 0x0004;
private const int LEFTDOWN = 0x0002;
public form1()
{
InitializeComponent();
}
private void clicktimer_Tick(object sender, EventArgs e)
{
Random rnd = new Random();
int maxcps = (int)Math.Round(1000.0 / (trackBar1.Value + trackBar2.Value * 0.2));
int mincps = (int)Math.Round(1000.0 / (trackBar1.Value + trackBar2.Value * 0.4));
try
{
clicktimer.Interval = rnd.Next(mincps, maxcps);
}
catch
{
//Ignored
}
bool mousdown = MouseButtons == MouseButtons.Left;
if (mousdown)
{
mouse_event(dwFlags:LEFTDOWN, dx:0,dy:0,cButtons:0,dwExtraInfo:0);
Thread.Sleep(millisecondsTimeout: rnd.Next(1, 6));
mouse_event(dwFlags: LEFTUP, dx: 0, dy: 0, cButtons: 0, dwExtraInfo: 0);
}
}
private void button1_Click(object sender, EventArgs e)
{
if (button1.Text.Contains("on"))
{
clicktimer.Start();
button1.Text = "Toggle: off";
}
else
{
clicktimer.Stop();
button1.Text = "Toggle: on";
}
}
}
}
I can suggest you to change the portion of code where you click with the following:
int X = Cursor.Position.X;
int Y = Cursor.Position.Y;
mouse_event(LEFTDOWN | LEFTUP, X, Y, 0, 0);
I think that your problem is that you start clicking but always in the position of the screen at the coordinates (0, 0) so nothing happens.
Also you don't actually need a timeout from the LEFTDOWN action and the LEFTUP one
If you don't want to click where your cursor is just set X and Y with your desired values (coordinates)

Needing create a Modal Dialog like UAC with a background screenshot

Based in this example i'm wanting create a Modal Dialog Form inside new desktop created by CreateDesktop api. Until now i'm able to show Modal Dialog Form inside new desktop, but i don't know how create a background window with screenshot for also show inside new desktop together Modal Dialog Form.
So, someone can help me with this task?
Thank you to all.
DlgMain.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
namespace ScreenLockerDemo
{
public partial class DlgMain : Form
{
public DlgMain()
{
InitializeComponent();
}
[DllImport("user32.dll")]
public static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags, uint dwDesiredAccess, IntPtr lpsa);
[DllImport("user32.dll")]
private static extern bool SwitchDesktop(IntPtr hDesktop);
[DllImport("user32.dll")]
public static extern bool CloseDesktop(IntPtr handle);
[DllImport("user32.dll")]
public static extern bool SetThreadDesktop(IntPtr hDesktop);
[DllImport("user32.dll")]
public static extern IntPtr GetThreadDesktop(int dwThreadId);
[DllImport("kernel32.dll")]
public static extern int GetCurrentThreadId();
enum DESKTOP_ACCESS : uint
{
DESKTOP_NONE = 0,
DESKTOP_READOBJECTS = 0x0001,
DESKTOP_CREATEWINDOW = 0x0002,
DESKTOP_CREATEMENU = 0x0004,
DESKTOP_HOOKCONTROL = 0x0008,
DESKTOP_JOURNALRECORD = 0x0010,
DESKTOP_JOURNALPLAYBACK = 0x0020,
DESKTOP_ENUMERATE = 0x0040,
DESKTOP_WRITEOBJECTS = 0x0080,
DESKTOP_SWITCHDESKTOP = 0x0100,
GENERIC_ALL = (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU |
DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK |
DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | DESKTOP_SWITCHDESKTOP),
}
private void buttonLockScreen_Click(object sender, EventArgs e)
{
// old desktop's handle, obtained by getting the current desktop assigned for this thread
IntPtr hOldDesktop = GetThreadDesktop(GetCurrentThreadId());
// new desktop's handle, assigned automatically by CreateDesktop
IntPtr hNewDesktop = CreateDesktop("RandomDesktopName", IntPtr.Zero, IntPtr.Zero, 0, (uint)DESKTOP_ACCESS.GENERIC_ALL, IntPtr.Zero);
// switching to the new desktop
SwitchDesktop(hNewDesktop);
// running on a different thread, this way SetThreadDesktop won't fail
Task.Factory.StartNew(() =>
{
// assigning the new desktop to this thread - so the Modal Dialog Form will be shown in the new desktop)
SetThreadDesktop(hNewDesktop);
Background Bkgfrm = new Background();
Bkgfrm.Show();
DlgLock DialogLock = new DlgLock();
DialogLock.ShowDialog(Bkgfrm);
}).Wait(); // waits for the task to finish
// end of modal form
// if got here, the form is closed => switch back to the old desktop
SwitchDesktop(hOldDesktop);
// disposing the secure desktop since it's no longer needed
CloseDesktop(hNewDesktop);
}
}
}
DlgLock.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ScreenLockerDemo
{
public partial class DlgLock : Form
{
public DlgLock()
{
InitializeComponent();
}
private void buttonClose_Click(object sender, EventArgs e)
{
Close();
}
}
}
Background.cs
namespace ScreenLockerDemo
{
public partial class Background : Form
{
public Background()
{
InitializeComponent();
}
private void print(Bitmap BM, PaintEventArgs e)
{
Graphics graphicsObj = e.Graphics;
graphicsObj.DrawImage(BM, 60, 10);
// graphicsObj.Dispose();
}
public void Background_Load(object sender, EventArgs e)
{
Paint += new PaintEventHandler(Background_Paint);
}
private void Background_Paint(object sender, PaintEventArgs e)
{
Rectangle rect = Screen.PrimaryScreen.Bounds;
int color = Screen.PrimaryScreen.BitsPerPixel;
PixelFormat pf;
pf = PixelFormat.Format32bppArgb;
Bitmap BM = new Bitmap(rect.Width, rect.Height, pf);
// Bitmap BM = new Bitmap(Image.FromFile(#"C:\Users\NZT48\Desktop\ScreenLockerDemo\bin\Debug\1.jpg"), rect.Width, rect.Height);
Graphics g = Graphics.FromImage(BM);
g.CopyFromScreen(rect.Left, rect.Top, 0, 0, rect.Size);
Bitmap bitamp = new Bitmap(BM);
print(bitamp, e);
}
private void Background_Shown(object sender, EventArgs e)
{
// Paint += new PaintEventHandler(Background_Paint);
}
}
}

how to lower cpu impact when dealing with slimdx

i am making an app that overlays other d3d games,
the app is working perfectly except it has a huge performance impact on the cpu
taking 21.4 % of the cpu when rendering only a single line !
i am using slimdx library on c# and here is my full code
OverLay.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SlimDX.Direct3D11;
using SlimDX.Windows;
using System.Runtime.InteropServices;
using System.Security;
using SlimDX;
using SlimDX.DXGI;
using Device = SlimDX.Direct3D9.Device;
using Resource = SlimDX.Direct3D9.Resource;
using System.Threading;
using D3D = SlimDX.Direct3D9;
namespace OverlayForm
{
public partial class OverLay : RenderForm
{
RenderForm form;
Device device;
// D3D.Sprite sprite;
public OverLay()
{
InitializeComponent();
Paint += OverLay_Paint;
FormBorderStyle = FormBorderStyle.None;
ShowIcon = false;
ShowInTaskbar = false;
TopMost = true;
WindowState = FormWindowState.Maximized;
//Make the window's border completely transparant
//SetWindowLong(Handle , GWL_EXSTYLE , (IntPtr)(GetWindowLong(Handle , GWL_EXSTYLE) ^ WS_EX_LAYERED ^ WS_EX_TRANSPARENT));
SetWindowLong(Handle , GWL_EXSTYLE , (IntPtr)(GetWindowLong(Handle , GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TRANSPARENT));
//Set the Alpha on the Whole Window to 255 (solid)
SetLayeredWindowAttributes(Handle , 0 , 255 , LWA_ALPHA);
form = this;
form.FormClosing += Form_FormClosing;
//Init DirectX
//This initializes the DirectX device. It needs to be done once.
//The alpha channel in the backbuffer is critical.
D3D.PresentParameters presentParameters = new D3D.PresentParameters();
presentParameters.Windowed = true;
presentParameters.SwapEffect = D3D.SwapEffect.Discard;
presentParameters.BackBufferFormat = D3D.Format.A8R8G8B8;
device = new Device(new D3D.Direct3D() , 0 , D3D.DeviceType.Hardware , Handle ,
D3D.CreateFlags.HardwareVertexProcessing , presentParameters);
//sprite = new D3D.Sprite(device);
font = new D3D.Font(device , new Font("Arial" , 9 , FontStyle.Regular));
line = new D3D.Line(this.device);
MessagePump.Run(form , new MainLoop(dxThread));
}
private void Form_FormClosing(object sender , FormClosingEventArgs e)
{
device.Dispose();
}
int centerx = Screen.PrimaryScreen.WorkingArea.Width / 2;
int centery = Screen.PrimaryScreen.WorkingArea.Height / 2;
private void OverLay_Paint(object sender , PaintEventArgs e)
{
//Create a margin (the whole form)
marg.Left = 0;
marg.Top = 0;
marg.Right = Width;
marg.Bottom = Height;
//Expand the Aero Glass Effect Border to the WHOLE form.
// since we have already had the border invisible we now
// have a completely invisible window - apart from the DirectX
// renders NOT in black.
DwmExtendFrameIntoClientArea(Handle , ref marg);
}
private static D3D.Font font;
private static D3D.Line line;
private void dxThread()
{
form.TopMost = true;
device.SetRenderState(D3D.RenderState.ZEnable , false);
device.SetRenderState(D3D.RenderState.Lighting , false);
device.SetRenderState(D3D.RenderState.CullMode , D3D.Cull.None);
device.SetTransform(D3D.TransformState.Projection , Matrix.OrthoOffCenterLH(0 , Width , Height , 0 , 0 , 1));
device.BeginScene();
//DrawFilledBox(0 , 0 , 100 , 100 , Color.White);
//font.DrawString( null, "Swag" , 10, 10 , new Color4(Color.White));
//DrawBox(0 , 0 , 10 , 10 , 1 , Color.Green);
DrawLine(0 , 0 , Screen.PrimaryScreen.Bounds.Width , Screen.PrimaryScreen.Bounds.Height , 2 , Color.Pink);
device.EndScene();
device.Present();
}
public static void DrawFilledBox(float x , float y , float w , float h , Color Color)
{
Vector2[] vLine = new Vector2[2];
line.GLLines = true;
line.Antialias = false;
line.Width = w;
vLine[0].X = x + w / 2;
vLine[0].Y = y;
vLine[1].X = x + w / 2;
vLine[1].Y = y + h;
line.Begin();
line.Draw(vLine , new Color4(Color));
line.End();
}
public static void DrawLine(float x1 , float y1 , float x2 , float y2 , float w , Color Color)
{
Vector2[] vLine = new Vector2[2] { new Vector2(x1 , y1) , new Vector2(x2 , y2) };
line.GLLines = true;
line.Antialias = false;
line.Width = w;
line.Begin();
line.Draw(vLine , new Color4(Color));
line.End();
}
public static void DrawBox(float x , float y , float w , float h , float px , System.Drawing.Color Color)
{
DrawFilledBox(x , y + h , w , px , Color);
DrawFilledBox(x - px , y , px , h , Color);
DrawFilledBox(x , y - px , w , px , Color);
DrawFilledBox(x + w , y , px , h , Color);
}
#region Extras
private Margins marg;
//this is used to specify the boundaries of the transparent area
internal struct Margins
{
public int Left, Right, Top, Bottom;
}
[DllImport("user32.dll" , SetLastError = true)]
private static extern UInt32 GetWindowLong(IntPtr hWnd , int nIndex);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd , int nIndex , IntPtr dwNewLong);
[DllImport("user32.dll")]
static extern bool SetLayeredWindowAttributes(IntPtr hwnd , uint crKey , byte bAlpha , uint dwFlags);
public const int GWL_EXSTYLE = -20;
public const int WS_EX_LAYERED = 0x80000;
public const int WS_EX_TRANSPARENT = 0x20;
public const int LWA_ALPHA = 0x2;
public const int LWA_COLORKEY = 0x1;
[DllImport("dwmapi.dll")]
static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd , ref Margins pMargins);
#endregion
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace OverlayForm
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
using (OverLay x = new OverLay())
{
}
}
}
}
Please note :
i already saw this : Very high CPU usage directx 9
but i am using MessagePump.Run and don't know how to apply the answer.
The reason for the high CPU is that SlimDX is using PeekMessage rather than the more usual GetMessage (that the majority of Windows apps use). The former does not wait for a message to appear in the message pump unlike the latter. In other words, GetMessage() will block the current thread possibly reducing the CPU load which is what you want a well-behaved Windows desktop application to do.
MSDN:
Retrieves a message from the calling thread's message queue. The function dispatches incoming sent messages until a posted message is available for retrieval.
Unlike GetMessage, the PeekMessage function does not wait for a message to be posted before returning More...
Now a typical graceful Windows message pump looks like this:
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
...however SlimDX uses what some people refer to as an action game loop:
static bool AppStillIdle
{
get
{
Message msg;
return !PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
}
}
public void MainLoop()
{
// hook the application's idle event
Application.Idle += new EventHandler(OnApplicationIdle);
Application.Run(form);
}
void OnApplicationIdle(object sender, EventArgs e)
{
while (AppStillIdle)
{
// Render a frame during idle time (no messages are waiting)
RenderFrame();
}
}
With nothing to draw you will experience a very tight loop of PeekMessage with no waiting in between!
My suggestion is that you either use one of the MessagePump.Run overloads for idle, or add a sleep as per below:
Change this:
void OnApplicationIdle(object sender, EventArgs e)
{
while (AppStillIdle)
{
// Render a frame during idle time (no messages are waiting)
RenderFrame();
}
}
...to this:
void OnApplicationIdle(object sender, EventArgs e)
{
while (AppStillIdle)
{
// Render a frame during idle time (no messages are waiting)
RenderFrame();
Thread.Sleep(0); // <------------- be graceful
}
}
Note the use of Thread.Sleep(0). This pauses for the minimal amount of time whilst still allowing the thread to be relinquished to the OS.
MSDN:
The number of milliseconds for which the thread is suspended. If the value of the millisecondsTimeout argument is zero, the thread relinquishes the remainder of its time slice to any thread of equal priority that is ready to run. If there are no other threads of equal priority that are ready to run, execution of the current thread is not suspended.
I see in your answer you already had a Thread.Sleep(50) but now it is good to know why SlimDX requires a Sleep in the first place and that 50 is perhaps too high a value.
GetMessage
OP:
i won't need a very active rendering mechanism, because i will only use this to show overlay from my music player about current song playing , next song , etc
Considering this is the case, the most CPU-efficient means is to replace your action loop with a turn-based game loop using GetMessage() instead of PeekMessage(). Then put your rendering in your application's OnIdle() callback.
As Nick Dandoulakis says in Windows Game Loop 50% CPU on Dual Core:
Nick:
That's a standard game loop for action games, where you must update objects positions / game world.
If you are making a board game GetMessage would be a better choice.
It really depends on what game you are making. More...
No Sleep() required.
the problem was that i was using full power of cpu even when not rendering, so adding
Thread.Sleep(50);
at the end of the dxThread method lowered it to only

Windows Forms - MdiClient scroll bars not automatically appearing as expected

I'm writing a windows forms application in C# whereby some windows utilities can be launched (e.g. CMD prompt, Registry editor, Events Viewer etc) and placed in an MdiClient control on the main form.
Everything is working great except that the scroll bars in the MdiClient control aren't automatically appearing when a child window falls beyond the MdiClient's borders. If the child windows were windows forms then I know that the MdiClient's scroll bars would automatically appear as expected. I've tried many things, including some complex workarounds.. and i'm beginning to think there must be something i'm completely overlooking.
I have attached some sample code below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
namespace MdiClient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
System.Windows.Forms.MdiClient mdiClient = new System.Windows.Forms.MdiClient();
mdiClient.Dock = DockStyle.Fill;
mdiClient.BackColor = Color.WhiteSmoke;
this.Controls.Add(mdiClient);
int processID = StartCMD();
AddToMDIClient(processID, mdiClient.Handle);
}
private int StartCMD()
{
int processID = -1;
using (Process process = new Process())
{
ProcessStartInfo startInfo = process.StartInfo;
startInfo.FileName = "cmd.exe";
try
{
process.Start();
processID = process.Id;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
return processID;
}
private void AddToMDIClient(int processID, IntPtr mdiClientHandle)
{
try
{
Process process = Process.GetProcessById(processID);
int numberOfAttempts = 0;
while (string.IsNullOrEmpty(process.MainWindowTitle) && numberOfAttempts < 30)//max of 3 seconds
{
Thread.Sleep(100);
process.Refresh();
numberOfAttempts++;
}
if (!string.IsNullOrEmpty(process.MainWindowTitle))
{
SetWindowPos(process.MainWindowHandle, HWND_TOPMOST, 1, 1, 0, 0, TOPMOST_FLAGS);
SetParent(process.MainWindowHandle, mdiClientHandle);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public const UInt32 TOPMOST_FLAGS = /*SWP_NOMOVE | */SWP_NOSIZE;
public const UInt32 SWP_NOSIZE = 0x0001;
}
}
The screenshot below shows that when the CMD window is moved so its borders are outside the borders of the MdiClient there are no scroll bars:
Please see this link for the image: http://picasaweb.google.com/lh/photo/75rMVJMCWRg_s_DFF6LmNg?authkey=Gv1sRgCIKRlsu8xuDh8AE&feat=directlink
Any help would be much appreciated!
Thanks,
Shady
Without the screenshot it is hard to say, but I think the way you create the MDIParanet is way too complicated.
private void Form1_Load(object sender, EventArgs e)
{
// System.Windows.Forms.MdiClient mdiClient = new System.Windows.Forms.MdiClient();
// mdiClient.Dock = DockStyle.Fill;
// mdiClient.BackColor = Color.WhiteSmoke;
// this.Controls.Add(mdiClient);
this.IsMdiContainer = true;
int processID = StartCMD();
AddToMDIClient(processID, mdiClient.Handle);
}
If you need the Client, you can filter it from Controls.
Another problem might be setting a MDIChild as TOP_MOST, I don't think that's a good combination.
I have been doing some testing and it work ok for me was long as I have Autoscroll = true in the forms properties.
Also, I noticed if you enlarge the form and move the command window to say the bottom right it will not show the scroll bars, it will only when you minimize the form past the command windows (see screenshots below)
Screenshot 1
http://picasaweb.google.com/lh/photo/rfwm-S8y06Fl3HFNshgj3g?feat=directlink
Screenshot 2
http://picasaweb.google.com/lh/photo/y6qkN9Jj19vDGFNkTuL4FQ?feat=directlink
Also, can you set on the Form's properties AutoScrollMinSize, so that you always have scroll bars in the form is smaller than the size set
Hope that helps
Josh

Categories