zoukankan      html  css  js  c++  java
  • WinForm应用程序中的ComboBox实现ReadOnly功能

    今天在做软件时遇到了一个问题,记录下来,以后备用,呵呵:

    在ComboBox控件的DropDownStyle有三种属性:
    1.Simple 类似TextBox的外观,文本部分可以编辑,控件的Text值可显示,Items中的项要靠键盘“↑”、“↓”来选择。
    2.DropDown 文本部分可以编辑,控件的Text值可显示,Items中的项通过点击控件的“▼”出现的下拉选择框来选择。
    3.DropDownList 文本部分不可编辑,不能设置控件的Text值,Items中的项通过点击控件的“▼”出现的下拉选择框来选择。

    本来是要用类似DropDown 的样式,开始时设置控件的Text值作为提示,但在用户选择选项时,不能让他编辑选项的内容,本来以为会有个ReadOnly属性
    然后设置一下就可以了,可没想到把属性列表挨个看了好几遍就是没找到,真不知道MS当时设计控件时怎么想的,只好查资料看能不能实现那样的功能,

    找了半天发现用windows API来实现比较简单(又是windows API看来windows API真的很好很强大)
    引用命名空间:
    using System.Runtime.InteropServices;
    用到的API声明:
    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
            public static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
            int GW_CHILD = 5;
           
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
            public const int EM_SETREADONLY = 0xcf;

    1.用GetWindow API取得要设置的ComboBox控件的句柄。
    2.用SendMessage API给取得的句柄设置只读属性。


    示例代码:

    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 WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
            public static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
            int GW_CHILD = 5;
           
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
            public const int EM_SETREADONLY = 0xcf;

            public Form1()
            {
                InitializeComponent();
                IntPtr editHandle = GetWindow(comboBox1.Handle , GW_CHILD);
                SendMessage(editHandle,EM_SETREADONLY,1,0);
            }        
        }
    }


    别人解释的用到的原理:
    1.comboBox其实是一个嵌套控件(复合控件)在DropDownList状态时;他由下拉列表,和ComboBox本身组成
      DropDown状态时ComboBox中多了一个edit就是.net下的TextBox那个输入状态是由edit控制的;
      不过这个edit是无法在.net下取得的this.comboBox1.Controls.Count 返回 0.
    2.用AIP取得控件句柄。
    3.给控件设置只读状态。
      这个就是发个消息基本可以搞定(不过忘记是那个消息了),看看msdn找em_ 开头的消息,找到EM_SETREADONLY看名字就是他了;
      根据SDK规则,em_ 开头的消息都是对应edit的.

  • 相关阅读:
    移动零【283】
    下一个排列【31】
    插入区间【57】
    有效的山脉数组【941】
    两个数组的交集【349】
    求根到叶子节点数字之和【129】
    解决已经pip 安装成功的第三方包,但总是标红或者运行报错import PendingDeprecationWarning
    String、StringBuffer与StringBuilder之间区别
    《Java 核心技术第 10 版》-- 读书笔记
    【转载】如何保证消息不被重复消费?
  • 原文地址:https://www.cnblogs.com/liukemng/p/1896469.html
Copyright © 2011-2022 走看看