OVH Cloud OVH Cloud

Subclassing de fenetre via NativeWindow

1 réponse
Avatar
Laura Martignas
Bonjour à tous

Je suis en train d'essayer de subclasser la fenetre principale du
logiciel Winamp, dans le but de développer une application destinée à
piloter ce logiciel. Pour test, j'essaie d'intercepter la fermeture de la
fenêtre en interceptant WM_CLOSE pour afficher une MessageBox, mais ça ne
marche pas du tout, pourtant le code semble correct... Voyez vous une
anomalie ? Le programme de test se compose d'une form et de 2 boutons :
le 1er bouton active le subclassing, le second le désactive.

Le code de la classe héritant de NativeWindow :

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WinampTest
{
public delegate void WAHandler(object sender, EventArgs e);

public class WAWindow : NativeWindow, IDisposable
{
bool disposed;
public event WAHandler WAEvent;
bool subclassed;

public bool Subclassed
{
get { return subclassed; }
set { subclassed = value; }
}

public WAWindow(IntPtr hwnd)
{
AssignHandle(hwnd);
}

protected override void WndProc(ref Message m)
{
if (subclassed)
{
if (m.Msg == 0x0010) // WM_CLOSE
WAEvent(this, null);
}
base.WndProc(ref m);
}

public void Dispose()
{
if (!disposed)
{
ReleaseHandle();
GC.SuppressFinalize(this);
disposed = true;
}
}

~WAWindow()
{
Dispose();
}
}
}


Et celui de mon programme de test :

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;
using System.Threading;

namespace WinampTest
{
public partial class Form1 : Form
{
WAWindow w;
IntPtr hwnd;

const int WM_WA_IPC = 0x400;
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string
lpWindowName);

public Form1()
{
InitializeComponent();
hwnd = FindWindow("Winamp v1.x", null);
w = new WAWindow(hwnd);
w.WAEvent += new WAHandler(w_WAEvent);
}

void w_WAEvent(object sender, EventArgs e)
{
MessageBox.Show("Coucou");
}

private void button1_Click(object sender, EventArgs e)
{
w.Subclassed = true;
}

private void button2_Click(object sender, EventArgs e)
{
w.Subclassed = false;
}
}
}

Voila, rien de bien sorcier :)
Voyez vous ce qui cloche ?

Merci par avance
Laura

1 réponse

Avatar
Paul Bacelar
Utilisez Spy++ pour savoir quel fenêtre resoit quel message.
--
Paul Bacelar
MVP VC++

"Laura Martignas" wrote in message
news:
Bonjour à tous

Je suis en train d'essayer de subclasser la fenetre principale du
logiciel Winamp, dans le but de développer une application destinée à
piloter ce logiciel. Pour test, j'essaie d'intercepter la fermeture de la
fenêtre en interceptant WM_CLOSE pour afficher une MessageBox, mais ça ne
marche pas du tout, pourtant le code semble correct... Voyez vous une
anomalie ? Le programme de test se compose d'une form et de 2 boutons :
le 1er bouton active le subclassing, le second le désactive.

Le code de la classe héritant de NativeWindow :

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WinampTest
{
public delegate void WAHandler(object sender, EventArgs e);

public class WAWindow : NativeWindow, IDisposable
{
bool disposed;
public event WAHandler WAEvent;
bool subclassed;

public bool Subclassed
{
get { return subclassed; }
set { subclassed = value; }
}

public WAWindow(IntPtr hwnd)
{
AssignHandle(hwnd);
}

protected override void WndProc(ref Message m)
{
if (subclassed)
{
if (m.Msg == 0x0010) // WM_CLOSE
WAEvent(this, null);
}
base.WndProc(ref m);
}

public void Dispose()
{
if (!disposed)
{
ReleaseHandle();
GC.SuppressFinalize(this);
disposed = true;
}
}

~WAWindow()
{
Dispose();
}
}
}


Et celui de mon programme de test :

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;
using System.Threading;

namespace WinampTest
{
public partial class Form1 : Form
{
WAWindow w;
IntPtr hwnd;

const int WM_WA_IPC = 0x400;
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string
lpWindowName);

public Form1()
{
InitializeComponent();
hwnd = FindWindow("Winamp v1.x", null);
w = new WAWindow(hwnd);
w.WAEvent += new WAHandler(w_WAEvent);
}

void w_WAEvent(object sender, EventArgs e)
{
MessageBox.Show("Coucou");
}

private void button1_Click(object sender, EventArgs e)
{
w.Subclassed = true;
}

private void button2_Click(object sender, EventArgs e)
{
w.Subclassed = false;
}
}
}

Voila, rien de bien sorcier :)
Voyez vous ce qui cloche ?

Merci par avance
Laura