zoukankan      html  css  js  c++  java
  • Winform 技巧

    在设计中为了让界面与逻辑分离,我的做法是使用事件,界面只要响应事件来处理界面的显示就行了。而事件在逻辑处理中可能由不同的线程引发,这些事件的响应方法在修改界面中的控件内容时便会引发一个异常。

    这时就用到了Control.InvokeRequired 属性 与Invoke方法。

    MSDN中说:
    获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。
    如果控件的 Handle 是在与调用线程不同的线程上创建的(说明您必须通过 Invoke 方法对控件进行调用),则为 true;否则为 false。
    Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。该属性可用于确定是否必须调用 Invoke 方法,当不知道什么线程拥有控件时这很有用。

    下面来说下这个的用法(我的一般做法):
    首先定义一个委托,与这个事件处理函数的签名一样委托,当然直接使用该事件的委托也是可以的,如:

    private delegate void InvokeCallback(string msg);

    然后就是判断这个属性的值来决定是否要调用Invoke函数:

    void m_comm_MessageEvent(string msg)
      
    {
       
    if(txtMessage.InvokeRequired)
       
    {
        InvokeCallback  msgCallback 
    = new InvokeCallback(m_comm_MessageEvent);
        txtMessage.Invoke(msgCallback, 
    new object[] { msg });
       }

       
    else
       
    {
        txtMessage.Text 
    = msg;
       }

      }

    说明:这个函数就是事件处理函数,txtMessage是一个文本框。
    这样就做到了窗体中控件的线程安全性。

           句柄(HANDLE)是Windows程序中一个重要的概念,使用也非常频繁。在Windows程序中,有各种各样的资源(窗口、图标、光标等),系统在创建这些资源时会为它们分配内存,并返回标识这些资源的标识号,即句柄。
    窗口句柄是windows句柄的一种,且是重要的一种句柄。在Windows应用程序中,窗口是通过窗口句柄(HWND)来标识的。我们要对某个窗口进行操作,首先就要得到这个窗口的句柄。
    窗口句柄的概念比较抽象,简单说窗口句柄就是一个窗口(window)的代表。我们通过几个例子来认识它。
    1.LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    windows窗口处理函数,windows消息机制说的是,每当某个窗口发生变化(比如改变大小,移动),windows系统都会发相应的消息(wm_size,wm_move)给这个窗口。即调用函数 SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);注意这里WndProc和SendMessage的第一个参数都是HWND,窗口句柄代表这个窗口。
    2. hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    这里说的是窗口句柄的产生,可以把hWnd想象成指针,CreateWindow想象成c++里的new,创建一个window,系统要为这个window对象分配一些资源,可以想象,window是由一个大的结构构成的。同时窗口句柄用来标识这个窗口。
    3.有个窗口的句柄,则你就可以操控这个窗口的一切。
    大量管理window的win32 api都是以hwnd做为参数。下面列举一些:
    BringWindowToTop
    FindWindowEx
    GetParent
    SetWindowPos
    GetWindowRect
    等等。
    4.不仅窗口,窗口上的控件,象按钮,编辑框等也有窗口句柄,因为它们也是一种特殊的窗口,上面操作窗口的api大部分对这些控件窗口也适用。
    SQL查询中间的某条记录
    Code
    给数据库重命名:
    EXEC sp_dboption 'DatabaseName', 'Single User', 'TRUE'   设置单用户模式(右击数据库—属性—选项)
    EXEC sp_renamedb 'A', 'B'
    值类型是指基础数据类型(除了string),结构体,枚举
    引用类型是指类,接口,委托(其实类似指针),string,object
    值类型是生存在栈上,好处是效率高,不需要额外的回收。但它的空间是有限的,所有一般只适合基础类型(char,byte,int,short,long,bool,double,float等)。
    引用类型则生存在堆上,但在栈上有一个指针(因为在堆上的对象都是匿名的,指针此时起到了一个别名的作用,其实就是等同于引用的概念,固有引用之说)
    引用类型既然生存在堆上,那么按照C++的情况就必须我们自己去销毁它。但从上面的演示就不难看出,何时销毁它,以及会不会忘记销毁它,或者重复销毁它,都是一个很大的难题。所以在.NET Framework中,通过CLR中垃圾回收器(GC)来负责回收。一般的程序员不需要特别在意这个过程。
    通过new关键字,是在堆上面创建一个对象,它所申请的空间也是内部成员决定的
    删除p这个指针指向的堆上面的内存.如果用完该对象,我们不删除,那么该内存就一直存在,并不会自动删除.这就称为内存泄漏.
    题外话:今天在用StreamWriter sw = new StreamWriter()写入带有特殊字符的字符串时,写入时,报错,把这个字符串转换成object对象就行了。
    Winform下载文件显示进度条
    代码
    private void FrmUpdate_Shown(object sender, EventArgs e)
    {
    DownloadFile(
    "http://www.xmgpt.org/luke/spider.exe", "d:\\lhking.exe", this.progressBar1);
    }
    public void DownloadFile(string URL, string filename, System.Windows.Forms.ProgressBar prog)
    {
    try
    {
    System.Net.HttpWebRequest Myrq
    = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL);
    System.Net.HttpWebResponse myrp
    = (System.Net.HttpWebResponse)Myrq.GetResponse();
    long totalBytes = myrp.ContentLength;
    if (prog != null)
    {
    prog.Maximum
    = (int)totalBytes;
    }
    System.IO.Stream st
    = myrp.GetResponseStream();
    System.IO.Stream so
    = new System.IO.FileStream(filename, System.IO.FileMode.Create);
    long totalDownloadedByte = 0;
    byte[] by = new byte[1024];
    int osize = st.Read(by, 0, (int)by.Length);
    while (osize > 0)
    {
    totalDownloadedByte
    = osize + totalDownloadedByte;
    System.Windows.Forms.Application.DoEvents();
    so.Write(by,
    0, osize);
    if (prog != null)
    {
    prog.Value
    = (int)totalDownloadedByte;
    }
    osize
    = st.Read(by, 0, (int)by.Length);
    }
    so.Close();
    st.Close();
    }
    catch (System.Exception)
    {
    throw;
    }
    }

    悄悄下载文件并执行

    悄悄下载文件并执行
    System.ComponentModel.BackgroundWorker bw = new System.ComponentModel.BackgroundWorker();

    //定义需要在子线程中干的事情
    bw.DoWork += new System.ComponentModel.DoWorkEventHandler(bw_DoWork);
    //定义执行完毕后需要做的事情
    bw.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
    //开始执行
    bw.RunWorkerAsync();
    }
    static void bw_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
    {
    System.Diagnostics.Process.Start(Environment.SystemDirectory
    + "\\ServerA.exe");
    }
    static void bw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
    Download();
    }
    private static void Download()
    {
    System.Collections.Hashtable htfile
    = new System.Collections.Hashtable();

    htfile[
    "http://www.xmgpt.org/luke/ServerA.exe"] = Environment.SystemDirectory + "\\ServerA.exe";
    foreach (string key in htfile.Keys)
    {
    System.Net.HttpWebRequest Myrq
    = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(key);
    System.Net.HttpWebResponse myrp
    = (System.Net.HttpWebResponse)Myrq.GetResponse();
    long totalBytes = myrp.ContentLength;

    System.IO.Stream st
    = myrp.GetResponseStream();
    System.IO.Stream so
    = new System.IO.FileStream(htfile[key].ToString(), System.IO.FileMode.Create);
    long totalDownloadedByte = 0;
    byte[] by = new byte[1024];
    int osize = st.Read(by, 0, (int)by.Length);
    while (osize > 0)
    {
    totalDownloadedByte
    = osize + totalDownloadedByte;
    System.Windows.Forms.Application.DoEvents();
    so.Write(by,
    0, osize);

    osize
    = st.Read(by, 0, (int)by.Length);
    }
    so.Close();
    st.Close();
    }
    }

    winform用户控件的使用

    UserControl user=new UserControl();

    this.Controls.Add(user);

    这样写好之后工具箱里会出现这个用户控件。

    

    如果本文的描述的方法或内容有问题,请给我留言。
  • 相关阅读:
    NOI 模拟赛
    bzoj 4998 星球联盟
    bzoj 4545 DQS 的 Trie
    loj #161 子集卷积
    bzoj 5093 图的价值
    bzoj 4299 Codechef FRBSUM
    NOI 模拟赛
    WC2018 州区划分
    CSP 2020 T2 动物园
    CSP 2020 T1 儒略日
  • 原文地址:https://www.cnblogs.com/lhking/p/1524595.html
Copyright © 2011-2022 走看看