C#中API函数的调用,请指点!(50分)

  • 主题发起人 主题发起人 草在墙头
  • 开始时间 开始时间

草在墙头

Unregistered / Unconfirmed
GUEST, unregistred user!
我定义了一个transferAPI,如下:
class transferAPI
{
[StructLayout(LayoutKind.Sequential)]
private struct LPPOINT
{
public int X;
public int Y;
}
[DllImport("GDI32.DLL")]
static extern bool MovetoEx(IntPtr hdc,int X,int Y,LPPOINT lpPoint);
private int ordx;
private int ordy;
private LPPOINT m_point;
private Graphics m_g;
private IntPtr m_hDC;

public void begin
Move(Graphics g, int x,int y) //Call at MouseDown
{
m_g=g;
m_hDC=m_g.GetHdc();
ordx=x;
ordy=y;
m_point=new LPPOINT();
m_point.X=x;
m_point.Y=y;
}
public void Move(int x,int y) //call at MouseMove
{
MovetoEx(m_hDC,x,y,m_point);
}
}
然后我分别在form的mousedown和mousemove里调用begin
Move和Move,在触发Move时提示
“Additional information: Unable to find an entry point named MovetoEx in DLL GDI32.DLL.”
why??
 
注意大小写,MoveToEx
 
to happylcq:
改成MoveToEx(是我写错了)后,提示:
'Object reference not set to an instance of an object.'
why?
 
我试过了,没有问题呀.
 
to happylcq:
你就是用我的代码试的吗?你没有做任何修改吗?
那真是奇怪,我这边一直提示
'Object reference not set to an instance of an object.'
 
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Data.SqlClient;
using System.Text;
using System.Runtime.Remoting.Messaging;
using JuYuan.Lcq;
using System.Runtime.InteropServices;
namespace WindowsApplication1
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
///
class transferAPI
{
[StructLayout(LayoutKind.Sequential)]
private struct LPPOINT
{
public int X;
public int Y;
}
[DllImport("GDI32.DLL")]
static extern bool MoveToEx(IntPtr hdc,int X,int Y,LPPOINT lpPoint);
private int ordx;
private int ordy;
private LPPOINT m_point;
private Graphics m_g;
private IntPtr m_hDC;

public void begin
Move(Graphics g, int x,int y) //Call at MouseDown
{
m_g=g;
m_hDC=m_g.GetHdc();
ordx=x;
ordy=y;
m_point=new LPPOINT();
m_point.X=x;
m_point.Y=y;
}
public void Move(int x,int y) //call at MouseMove
{
MoveToEx(m_hDC,x,y,m_point);
}
}
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Data.SqlClient.SqlConnection sqlConnection1;
private System.Data.SqlClient.SqlCommand sqlCommand1;
private System.Data.DataView dataView1;
private System.Data.SqlClient.SqlCommand sqlSelectCommand1;
private System.Data.SqlClient.SqlCommand sqlInsertCommand1;
private System.Data.SqlClient.SqlCommand sqlUpdateCommand1;
private System.Data.SqlClient.SqlCommand sqlDeleteCommand1;
private System.Data.SqlClient.SqlDataAdapter sqlDataAdapter1;
private System.Windows.Forms.Label label1;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
private FileStream fileStm;
private byte[] readBuf;
private System.Windows.Forms.Button button2;
private static AsyncCallback Callback;
private transferAPI api;

public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.sqlConnection1 = new System.Data.SqlClient.SqlConnection();
this.sqlCommand1 = new System.Data.SqlClient.SqlCommand();
this.dataView1 = new System.Data.DataView();
this.sqlSelectCommand1 = new System.Data.SqlClient.SqlCommand();
this.sqlInsertCommand1 = new System.Data.SqlClient.SqlCommand();
this.sqlUpdateCommand1 = new System.Data.SqlClient.SqlCommand();
this.sqlDeleteCommand1 = new System.Data.SqlClient.SqlCommand();
this.sqlDataAdapter1 = new System.Data.SqlClient.SqlDataAdapter();
this.label1 = new System.Windows.Forms.Label();
this.button2 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.dataView1)).begin
Init();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(288, 32);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(8, 80);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(672, 296);
this.richTextBox1.TabIndex = 1;
this.richTextBox1.Text = "richTextBox1";
//
// sqlConnection1
//
this.sqlConnection1.ConnectionString = "data source=C://Documents and Settings//Administrator//Mydo
cuments//db1.mdb;password" +
"=/"/";user id=Admin";
//
// sqlCommand1
//
this.sqlCommand1.Connection = this.sqlConnection1;
//
// sqlDataAdapter1
//
this.sqlDataAdapter1.DeleteCommand = this.sqlDeleteCommand1;
this.sqlDataAdapter1.InsertCommand = this.sqlInsertCommand1;
this.sqlDataAdapter1.SelectCommand = this.sqlSelectCommand1;
this.sqlDataAdapter1.UpdateCommand = this.sqlUpdateCommand1;
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(232, 56);
this.label1.TabIndex = 2;
this.label1.Text = "label1";
//
// button2
//
this.button2.Location = new System.Drawing.Point(384, 32);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(120, 32);
this.button2.TabIndex = 3;
this.button2.Text = "button2";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(696, 421);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.button2,
this.label1,
this.richTextBox1,
this.button1});
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);
((System.ComponentModel.ISupportInitialize)(this.dataView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
api = new transferAPI();

}
private void button1_Click(object sender, System.EventArgs e)
{
Callback = new AsyncCallback(CallBackFunction);
fileStm = new FileStream(@"c:/key.txt", FileMode.Open, FileAccess.Read, FileShare.Read, 64, true);
readBuf = new byte[fileStm.Length];
fileStm.begin
Read(readBuf, 0, readBuf.Length, Callback, null);
for(long i = 0;
i < 5000;
i++)
{
if(i % 1000 == 0)
{
richTextBox1.Text += "Execution in Main" + i.ToString() + "/r";
}
}
MyClass1 myClass1 = new MyClass1();
}
private void CallBackFunction(IAsyncResult asyncResult)
{
int readB = fileStm.EndRead(asyncResult);
if(readB > 0)
{
fileStm.begin
Read(readBuf, 0, readBuf.Length, Callback, null);

richTextBox1.Text += Encoding.ASCII.GetString(readBuf, 0, readB);
}
}
private void button2_Click(object sender, System.EventArgs e)
{
}
private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
api.Move(e.X, e.Y);
}
}
}
你试试看
 
草在墙头:
你好
出错的原因是,你的这个方法
public void Move(int x,int y) //call at MouseMove
{
MovetoEx(m_hDC,x,y,m_point);
}
无条件的使用m_hDC,这是不对的,因为在FORM中move时,还没mouseDown,先mouseMove了,
所以,m_g没分配,m_hDC更没得到。
另外,m_hDC用完后必须释放,你参考我给你的例子。
m_g.ReleaseHdc(m_hDC);

还有就是设计的问题,
一。Api函数首先要静态的,无关的先封状起来,除了在封状的类中,能看到[DllImport("GDI32.DLL")] 外,
调用的逻辑中,不应该再出现它们。
//这是封状user32
public class USER32
{
[DllImport("USER32.DLL")]
public static extern int DrawFocusRect(IntPtr hdc,ref RECT lpRect);
[DllImport("USER32.DLL")]
public static extern bool ClientToScreen(IntPtr hWnd,ref Point lp);

[DllImport("User32.DLL")]
public static extern IntPtr GetActiveWindow ( );
}

public class Shell32
{...}
public class GDI32
{...}

二。类transferApi
1。名字改改吧,叫Move,Draw等类似的名字吧
2。类的成员不应该在一个正式干活的方法中复制
public void begin
Move(Graphics g, int x,int y) //Call at MouseDown
{
m_g=g;
m_hDC=m_g.GetHdc();
ordx=x;
ordy=y;
m_point=new LPPOINT();
m_point.X=x;
m_point.Y=y;
}
你应该在constructor或专门写个Initial()方法来完成成员的初始化
尤其是这两个成员
m_g=g;
m_hDC=m_g.GetHdc();

3。struct LPPOINT 是不需要new的,它是值类型的
chinaplate
20030519
 
> 2。类的成员不应该在一个正式干活的方法中复制
我的意思是说,类的成员不应该在一个正式干活的方法中才初始化
两外,
public void begin
Move(Graphics g, int x,int y)
public void Move(int x,int y)
这两个对称方法,参数不对称,begin
Move的g参数,应取消,成员m_g应提前初始化
似乎你还要加一个EndMove方法才更对称,用于释放m_hDC.
 
to chinaplate:
你的建议很对,谢谢你!
因为我现在在写一个类,我的代码只是这个类的一个具体实现的部分,所以在许多方面都没有考虑。
但是,我在form中做了控制,只有但mousedown执行之后才能执行mousemove,所以在开头您说的情况不存在。
我的整个代码:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
namespace WindowsApplication10
{
/// <summary>
/// Summary description for Form1.
/// </summary>
///
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
///
private System.ComponentModel.Container components = null;
private bool bMove=false;
private System.Windows.Forms.Button button1;
private transferAPI mytr;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support -do
not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(440, 296);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(112, 64);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(560, 381);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseDown);
this.Load += new System.EventHandler(this.Form1_Load);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseUp);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
bMove=true;
mytr.begin
Move(this.CreateGraphics(),e.X,e.Y);
}
private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
bMove=false;
}
private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (bMove)
{

mytr.Move(this.CreateGraphics(),e.X,e.Y);
}
}
private void Form1_Load(object sender, System.EventArgs e)
{
mytr=new transferAPI();
}
}
class transferAPI
{
[StructLayout(LayoutKind.Sequential)]
private struct LPPOINT
{
public int X;
public int Y;
}
[DllImport("GDI32.DLL")]
static extern bool MoveToEx(IntPtr hdc,int X,int Y,LPPOINT lpPoint);
[DllImport("GDI32.DLL")]
public static extern int SetROP2(IntPtr hdc,int nDrawMode);

private const int R2_NOTXORPEN = 10;
private LPPOINT m_point;
private Graphics m_g;
private IntPtr m_hDC;

public void begin
Move(Graphics g, int x,int y) //Call at MouseDown
{
m_g=g;
m_hDC=m_g.GetHdc();
//m_point=new LPPOINT();
m_point.X=x;
m_point.Y=y;
}
public void Move(int x,int y) //call at MouseMove
{
MoveToEx(m_hDC,x,y,m_point);
}
}
}
操作时只要一按下鼠标并拖动就出错。请指教!
 
[DllImport("GDI32.DLL")]
static extern bool MoveToEx(IntPtr hdc,int X,int Y,ref LPPOINT lpPoint);
MoveToEx(m_hDC,x,y,ref m_point);
 
谢谢两位大侠!!
 
后退
顶部