Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



WM_COMMAND od dynamicky vytvořeného buttonu

Seznam témat     Nová odpověď

Přihlásit se     Registrace     Zapomenuté heslo

Re: WM_COMMAND od dynamicky vytvořeného buttonu

Autor: Jaroslav Smid

22:31:16 01.07.2010

Poradím ti, pokud mi řekneš, proč špatně používáš WinAPI:

private int HookProc(int hdlg, int msg, int wParam, int lParam)

očividně nečteš dokumentaci, ale hdlg je HANDLE, wParam je WPARAM, lParam je LPARAM. A teď co to pro tebe znamená - v 32bit systému se jedná o 32bit hodnoty, v 64bit systému v 64bit .NETu se jedná o 64bit hodnoty. int je v obou případech 32bit. Už to vidíte? I když nemáte 64bit systém, je třeba WinAPI používat korektně, jinak si říkáte o maléry. Jap pro HANDLE, tak pro WPARAM a LPARAM použij v C# typ IntPtr, který má stejné vlastnosti (tj 32bit na 32bit systému a 64bit na 64bit systému).
To samé platí o návratové hodnotě, je to LRESULT, nebo v případě dialogu LONG_PTR, musíš tedy opět použít IntPtr.


m_lpfnOldWndProc = Win32Api.SetWindowLong( m_hPreviewButton, Win32Api.GWL_WNDPROC, new Win32Api.WNDProcDelegate( delBtnPreviewWndProc ) );

Je opět špatně. Pro nastavení procedury okna je potřeba použít SetWindowLong[bold]Ptr[/bold] (typ [bold]GWLP_WNDPROC[/bold]).

Atd, atd. Takže nemá cenu se do takových věcí pouštět, když jim jaksi nerozumíš. Nejprve nastuduj WinAPI a potom se pouštěj do "pokročilých" věcí.


A proč ti to vyčítám? Kvůli takovým nemehlům jako ty je pro Windows 5,5 64bit programů, i když jsou tu 64bit windows od roku 2003 (možná i dřív, nehodlám to zjišťovat). Protože jim kvůli takovýmhle kravinám padají (c#), nebo nejdou překompilovat bez chyb (c, c++).

Citovat příspěvek

 

Re: Cely kod - WM_COMMAND od dynamicky vytvořeného buttonu

Autor: Gandalf2

14:06:07 28.05.2010

[code]
private void button1_Click(object sender, System.EventArgs e)
{
ImportFileDialog ofd = new ImportFileDialog();

ofd.DefaultExt = "xml";
ofd.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
ofd.Caption = "xTm: Import Quad Preset";

ofd.ShowDialog();
}
}

public class ImportFileDialog
{
private const int m_hPreviewButtonId = 987 ;
private IntPtr m_hPreviewButton = IntPtr.Zero;

private Win32Api.WNDProcDelegate m_lpfnOldWndProc = null;

private string m_Caption = "";
private string m_Filter = "";
private string m_DefaultExt = "";
private string m_FileName = "";

private Screen m_ActiveScreen;

private int HookProc(int hdlg, int msg, int wParam, int lParam)
{
switch (msg)
{
case ( int ) Win32Api.WindowsMessages.WM_COMMAND:

switch ( wParam % 0xFFFF )
{
case m_hPreviewButtonId:
MessageBox.Show( "Click" );
break;
}
break;

case ( int ) Win32Api.WindowsMessages.WM_INITDIALOG:

Rectangle sr = m_ActiveScreen.Bounds;
Win32Api.RECT cr = new Win32Api.RECT();
IntPtr hWndParent = Win32Api.GetParent( ( IntPtr ) hdlg );
Win32Api.GetWindowRect( hWndParent, ref cr );

int x = ( sr.Right + sr.Left - ( cr.right - cr.left )) / 2;
int y = ( sr.Bottom + sr.Top - ( cr.bottom - cr.top )) / 2;
Win32Api.SetWindowPos( hWndParent, IntPtr.Zero, x, y, cr.right - cr.left, cr.bottom - cr.top + 28, Win32Api.SWP_NOZORDER );

IntPtr fileTypeWindow = Win32Api.GetDlgItem( hWndParent, 0x441 );
Win32Api.RECT aboveRect = new Win32Api.RECT();
Win32Api.GetWindowRect( fileTypeWindow, ref aboveRect );

Win32Api.POINT point = new Win32Api.POINT();
point.X=aboveRect.left;
point.Y=aboveRect.bottom;

Win32Api.ScreenToClient( hWndParent, ref point );

IntPtr hFont = Win32Api.SendMessage( fileTypeWindow, ( int ) Win32Api.WindowsMessages.WM_GETFONT, IntPtr.Zero, IntPtr.Zero );

IntPtr hCancelButton = Win32Api.GetDlgItem( hWndParent, 0x2 );
aboveRect = new Win32Api.RECT();
Win32Api.GetWindowRect( hCancelButton, ref aboveRect );

point = new Win32Api.POINT();
point.X = aboveRect.left;
point.Y = aboveRect.bottom;
Win32Api.ScreenToClient( hWndParent, ref point );

Win32Api.POINT rightPoint = new Win32Api.POINT();
rightPoint.X=aboveRect.right;
rightPoint.Y=aboveRect.top;

Win32Api.ScreenToClient( hWndParent, ref rightPoint );

IntPtr hPreviewButton = Win32Api.CreateWindowEx( 0, "Button", "Preview", ( uint ) ( Win32Api.WS_VISIBLE | Win32Api.WS_CHILD ),

point.X, point.Y + 4, rightPoint.X - point.X, 25, hWndParent, m_hPreviewButtonId, IntPtr.Zero, 0 );

m_lpfnOldWndProc = Win32Api.SetWindowLong( m_hPreviewButton, Win32Api.GWL_WNDPROC, new Win32Api.WNDProcDelegate( delBtnPreviewWndProc ) );

Win32Api.SendMessage( hPreviewButton, ( int ) Win32Api.WindowsMessages.WM_SETFONT, hFont, IntPtr.Zero );

m_hPreviewButton = hPreviewButton;

break;

case ( int ) Win32Api.WindowsMessages.WM_DESTROY:

if ( m_hPreviewButton != IntPtr.Zero )
{
Win32Api.DestroyWindow( m_hPreviewButton );
}

break;
}
return 0;
}

private int delBtnPreviewWndProc( int hWnd, int message, int wParam, int lParam )
{
switch ( message )
{
case ( int ) Win32Api.WindowsMessages.WM_LBUTTONDOWN:

if ( wParam % 0xFFFF == m_hPreviewButtonId )
{
MessageBox.Show( "Konecne" );
}

//!!! call old proc
break;
}
return 0;
}

public DialogResult ShowDialog()
{
Win32Api.OPENFILENAME ofn = new Win32Api.OPENFILENAME();

ofn.lStructSize= Marshal.SizeOf( ofn );
ofn.lpstrFilter= m_Filter.Replace('|', '\0') + '\0';

ofn.lpstrFile = m_FileName + new string(' ', 512);
ofn.nMaxFile = ofn.lpstrFile.Length;
ofn.lpstrFileTitle = System.IO.Path.GetFileName(m_FileName) + new string(' ', 512);
ofn.nMaxFileTitle = ofn.lpstrFileTitle.Length;
ofn.lpstrTitle = m_Caption;
ofn.lpstrDefExt = m_DefaultExt;

ofn.hwndOwner = Form.ActiveForm.Handle;

m_ActiveScreen = Screen.FromControl(Form.ActiveForm);

ofn.Flags = Win32Api.OFN_EXPLORER | Win32Api.OFN_PATHMUSTEXIST | Win32Api.OFN_NOTESTFILECREATE | Win32Api.OFN_ENABLEHOOK | Win32Api.OFN_HIDEREADONLY | Win32Api.OFN_OVERWRITEPROMPT;

ofn.lpfnHook = new Win32Api.OFNHookProcDelegate(HookProc);

if ( !Win32Api.GetOpenFileName( ref ofn ) )
{
int ret = Win32Api.CommDlgExtendedError();

if ( ret!=0 )
{
throw new ApplicationException("Couldn't show file open dialog - " + ret.ToString());
}

return DialogResult.Cancel;
}

m_FileName = ofn.lpstrFile;

return DialogResult.OK;
}
[/code]

Citovat příspěvek

 

Re: WM_COMMAND od dynamicky vytvořeného buttonu

Autor: Gandalf2

14:22:37 27.05.2010

Vím, jak se v CSharp dělá tlačtko, problém je, jak by asi byo možné umístit takové tlačítko na Common Win32API Dialog jako je GetOpenFileName. Připomínám, že .NET třída OpenFileDialog je sealed.:-( právě proto se to dělá pomocí WinAPI.

Nějaký další nápad?

Citovat příspěvek

 

Re: WM_COMMAND od dynamicky vytvořeného buttonu

Autor: Bart_Simpson

20:22:24 26.05.2010

Gandalf2 Napsal:
-------------------------------------------------------
> Jedná se o C#...

V C# se to takhle vůbec nedělá. Tady je ukázka jak se dělá dynamicky tlačítko v C#.
http://www.java2s.com/Code/CSharp/GUI-Windows-Form/Addbuttontoform.htm

Citovat příspěvek

 

Re: WM_COMMAND od dynamicky vytvořeného buttonu

Autor: Gandalf2

18:47:52 26.05.2010

Jedná se o C#, ale to nevadí. Při stisknutí tlačítka se HookProc nezavolá, nevím proč, proto soudím, že je chyba ve vytvoření tlčítka, nějakém příznaku apod.. Když jsem tam měl combobox, tak se volala a zpráva byla WM_NOTIFY - tedy vše v pořádku.

Citovat příspěvek

 

Re: WM_COMMAND od dynamicky vytvořeného buttonu

Autor: JiriValerian

17:21:39 26.05.2010

[code]case WM_COMMAND:
switch ([b][color=#FF0000]LOWORD(wParam)[/color][/b]) {
...[/code]

[b]BS_PUSHBUTTON[/b] je jen pseudo příznak, který se nedá odebrat a ani jej nemusíte psát.

Citovat příspěvek

 

Re: WM_COMMAND od dynamicky vytvořeného buttonu

Autor: GandalfThe2

15:21:47 26.05.2010

Přesněji řečeno, HookProc se vůbec nazavolá. Také nerozumím, proč je v hlavičkových souborech PlatformSDK rovno BS_PUSHBUTTON=0 - jak můžu takový styl přidávat / odebírat?
Díky

Citovat příspěvek

 

WM_COMMAND od dynamicky vytvořeného buttonu

Autor: GandalfThe2

15:15:17 26.05.2010

Dobrý den, potřeboval bych, prosím, radu. Mám takovou kombinaci C# a PInvoke(Winapi) a snažím se pomocí ní rozšířit klasický WinAPI OpenFileDialog metodou Hookování o jeden button navíc. Hookování mi funguje ( WM_INITDIALOG přijde, vše se krásně vykreslí. ) Problém je, že když na nově přidaný button kliknu, nikdy nepřijde WM_COMMAND. Díval jsem se do MSDN a pokud má button přidaný styl BS_PUSHBUTTON=0, měl by WM_COMMAND chodit. Tak nevím, kde je chyba. Nenapadá Vás prosím někoho něco?
Děkuji mnohokrát za případnou radu

[code]
private int HookProc(int hdlg, int msg, int wParam, int lParam)
{
const int WM_COMMAND = 273;

switch (msg)
{
case WM_COMMAND:
switch ( wParam % 0xFFFF )
{
case 111:
MessageBox.Show( "Click" );
break;
}
break;

case WM_INITDIALOG:

Rectangle sr = m_ActiveScreen.Bounds;
RECT cr=new RECT();
int hWndParent = GetParent( hdlg );
GetWindowRect( hWndParent, ref cr );

int x=( sr.Right + sr.Left - ( cr.Right-cr.Left )) / 2;
int y=( sr.Bottom + sr.Top - ( cr.Bottom-cr.Top )) / 2;
SetWindowPos( hWndParent, 0, x, y, cr.Right - cr.Left, cr.Bottom - cr.Top + 28, SWP_NOZORDER );

int fileTypeWindow = GetDlgItem( hWndParent, 0x441 );
RECT aboveRect=new RECT();
GetWindowRect(fileTypeWindow, ref aboveRect);

POINT point=new POINT();
point.X=aboveRect.Left;
point.Y=aboveRect.Bottom;

ScreenToClient( hWndParent, ref point );

int fontHandle=SendMessage( fileTypeWindow, WM_GETFONT, 0, 0 );

int fileCancelButton = GetDlgItem( hWndParent, 0x2 );
aboveRect = new RECT();
GetWindowRect( fileCancelButton, ref aboveRect );

point=new POINT();
point.X=aboveRect.Left;
point.Y=aboveRect.Bottom;
ScreenToClient( hWndParent, ref point );

POINT rightPoint=new POINT();
rightPoint.X=aboveRect.Right;
rightPoint.Y=aboveRect.Top;

ScreenToClient( hWndParent, ref rightPoint );

int hPreviewButton = CreateWindowEx( 0, "Button", "Preview", WS_VISIBLE | WS_CHILD | 0x00000000, point.X, point.Y + 4, rightPoint.X - point.X, 25, hWndParent, 111, 0, 0 );
SendMessage( hPreviewButton, WM_SETFONT, fontHandle, 0 );

m_hPreviewButton = hPreviewButton;

break;

case WM_DESTROY:


if ( m_hPreviewButton!=0 )
{
DestroyWindow( m_hPreviewButton );
}

break;
}
return 0;
}
[/code]

Citovat příspěvek

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: