Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: ЧАВО  (Прочитано 46933 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Dimyan
Гость
« : 08-01-2004 05:40 » 

В сети появилось много обсуждений, статей и споров по .Net!
Бесспорно, теория необходима, а в спорах рождается истина, но данный раздел посвящается практической помощи так необходимой любому программисту.
Итак, ПОЕХАЛИ!!!
« Последнее редактирование: 12-10-2008 10:48 от RXL » Записан
Dimyan
Гость
« Ответ #1 : 08-01-2004 05:48 » 

Содержание

1) Как сделать, чтобы форма не отображалась в Task Bar'e?
2) Как запретить пользователю перемещать форму?
3) Как убрать некоторые пункты из системного меню формы?
4) Как использовать API-функции в C#?
5) В ToolBar'e есть несколько кнопок, как определить на какой кнопке кликнули?
6) Как сделать чтоб форму можно было таскать мышкой уцепившись за любое место?
7) Как сделать полупрозрачной Panel?
8) Как реализовать панель, принимающую фокус?
9) Как создать форму с нестандартным видом?
10) Как выполнить эмуляцию кликов мыши?
11) Продолжение тут
Записан
Dimyan
Гость
« Ответ #2 : 08-01-2004 05:49 » 

1) Как сделать, чтобы форма не отображалась в Task Bar'e?

Установить свойство Form.ShowInTaskbar в значение false.
Записан
Dimyan
Гость
« Ответ #3 : 08-01-2004 05:55 » 

2) Как запретить пользователю перемещать форму?

Пользователь может перемещать форму 2-мя способами - перетаскивая ее мышью за заголовок и после выбора в системном меню пункта Move. Первую возможность можно подавить при помощи перехвата нажатий мыши на заголовке формы. Для этого во время обработки сообщения WM_NCLBUTTONDOWN проверим в каком именно месте не клиентской области была нажата мышь (при помощи посылки сообщения WM_NCHITTEST), и если это заголовок - то не пропускаем только-что принятое сообщение WM_NCLBUTTONDOWN в оконную процедуру для обработки по умолчанию, таким образом, нажатия будут игнорироваться. Вот пример, в котором форму можно перемещать только при помощи пункта меню Move:
Код:
class UnMovableForm: Form
{
 protected override void WndProc(ref Message m)
 {
  if (m.Msg == WM_NCLBUTTONDOWN)
  {
   //Проверяем где именно нажали кнопку мыши
   int result = SendMessage(m.HWnd, WM_NCHITTEST,
   IntPtr.Zero, m.LParam);
   if (result == HTCAPTION)
    //Не позволяем этому сообщению быть обработанным
    return;
  }
  base.WndProc(ref m);
 }
 static void Main()
 {
  Application.Run(new UnMovableForm());
 }
 //Win32 API функция и константы
 const int WM_NCLBUTTONDOWN = 0x00A1;
 const int WM_NCHITTEST = 0x0084;
 const int HTCAPTION = 2;
 [DllImport("User32.dll")]
 static extern int SendMessage(IntPtr hWnd,
 int Msg, IntPtr wParam, IntPtr lParam);
}
Если-же нужно запретить перемещать форму как при помощи перетаскивания за заголовок, так и при помощи пункта Move - то нужно лишь убрать из системного меню пункт Move, заменив там константу SC_CLOSE на SC_MOVE, определенную как:
Код:
const int SC_MOVE = 0xF010;
« Последнее редактирование: 23-11-2007 18:03 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #4 : 08-01-2004 05:57 » 

3) Как убрать некоторые пункты из системного меню формы?

При помощи Win32 API функций GetSystemMenu() и RemoveMenu():
Код:
class FormWithoutCloseButton: Form
{
//На момент вызова этого метода у нашей формы
//уже сформирован ее Handle (HWND)
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
//Получаем Handle системного меню
IntPtr hMenu = GetSystemMenu(Handle, false);
//и удаляем пункт "Move"
RemoveMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
}

static void Main()
{
Application.Run(new FormWithoutCloseButton());
}

//Необходимые Win32 API функции и константы
const int SC_CLOSE = 0xF060;
const int MF_BYCOMMAND = 0;

[DllImport("User32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

[DllImport("User32.dll")]
static extern bool RemoveMenu(IntPtr hMenu, int uPosition, int uFlags);
}
« Последнее редактирование: 23-11-2007 18:05 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #5 : 08-01-2004 06:06 » 

4) Как использовать API-функции в C#?

Для использования в программе API-функций надо, во-первых, добавить постранство имен System.Runtime.InteropServices, во-вторых, добавить заголовок нужной API-функции и в-третьих, вызвать ее в нужном месте.

Код:
using System;
...
//Добавление пространства имен
using System.Runtime.InteropServices;
...
        //Добавление заголовка
[DllImport("user32.dll", EntryPoint="MessageBox")]
        public static extern int MessageBox(int hWnd,
        String strMessage, String strCaption, uint uiType);
...
private void button1_Click(object sender, System.EventArgs e)
        {
            //Вызов API-функции
            MessageBox(0, "Hello!", "Caption", 0);
        }
    ...
В указанном примере при нажатии на кнопку выскочит MessageBox (путем вызова соответствующей API-функции).
« Последнее редактирование: 23-11-2007 18:06 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #6 : 08-01-2004 06:21 » 

5) В ToolBar'e есть несколько кнопок, как определить на какой кнопке кликнули?

У класса ToolBar есть событие ButtonClick, аргументом этого события является класс ToolBarButtonClickEventArgs, содержащий в том числе и свойство Button, идентифицирующее кнопку, по которой щелкнули. Чтобы узнать индекс этой кнопки в коллекции ToolBar.Buttons нужно вызвать метод IndexOf этой коллекции (ToolBarButtonCollection):
Код:
void OnToolBarButtonClick(object sender, ToolBarButtonClickEventArgs e)
{
 switch(((ToolBar)sender).Buttons.IndexOf(e.Button))
 {
  case 0:
   // ...
   break;
 
  case 1:
   // ...
   break;
 }
}

Конечно же, при необходимости, в обработчике клика можно идентифицировать кнопку и по каким-то ее свойствам, например Text или Tag.
« Последнее редактирование: 23-11-2007 18:11 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #7 : 08-01-2004 10:52 » 

6) Как сделать чтоб форму можно было таскать мышкой уцепившись за любое место?

Код:
//переменные класса
private bool isDragging = false;
private Point oldPos;

//в конструкторе
this.MouseDown += new MouseEventHandler(MyForm_MouseDown);
this.MouseMove += new MouseEventHandler(MyForm_MouseMove);
this.MouseUp += new MouseEventHandler(MyForm_MouseUp);

//методы
private void MyForm_MouseDown(object sender, MouseEventArgs e)
{
 this.isDragging = true;
 this.oldPos = new Point();
 this.oldPos.X = e.X;
 this.oldPos.Y = e.Y;
}

private void MyForm_MouseMove(object sender, MouseEventArgs e)
{
 if(this.isDragging)
 {
  Point tmp = new Point(this.Location.X, this.Location.Y);
  tmp.X += e.X - this.oldPos.X;
  tmp.Y += e.Y - this.oldPos.Y;
  this.Location = tmp;
 }
}

private void MyForm_MouseUp(object sender, MouseEventArgs e)
{
 this.isDragging = false;
}
« Последнее редактирование: 23-11-2007 18:12 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #8 : 10-01-2004 06:54 » new

7) Как сделать полупрозрачной Panel?

Если нужно чтобы было видно только изображение (не Control'ы), находящееся под ней, то достаточно у Panel'и выставить свойство BackColor в значение цвета, содержащее alpha-состовляющую в диапазоне 0 - 254. Вот пример установки наполовину прозрачного красного фона для кнопки:
Код:
button.BackColor = Color.FromArgb)125, Color.Red:;
Только нужно иметь ввиду, что для того, чтобы Control поддерживал прозрачные цвета - у него должны быть выставлены стили ControlStyles.SupportsTransparentBackColor и ControlStyles.UserPaint. Например, у Button и Panel эти стили выставлены, а вот, например, у TextBox'а - нет.
Если же нужно, чтобы под панелью было видно не только нарисованное изображение, но и низлежащие 'сестринские' (имеющие того же родителя) control'ы - у нее при создании нужно выставить стиль WS_EX_TRANSPARENT, указывающий окну, что сперва должны прорисоваться низлежащие 'сестринские' окна:
Код:
class TransparentPanel: Panel
{
 //Чтобы background не прорисовывался выставим флаг ControlStyles.Opaque:
 public TransparentPanel()
 {
  SetStyle(ControlStyles.Opaque, true);
 }

 //И добавим к окну, при его создании, стиль WS_EX_TRANSPARENT:
 protected override CreateParams CreateParams
 {
  get
  {
   const int WS_EX_TRANSPARENT = 0x00000020;
   CreateParams createParams = base.CreateParams;
   createParams.ExStyle |= WS_EX_TRANSPARENT;
   return createParams;
  }
 }
 //Теперь, чтобы панель была видна как полупрозрачная, необходимо переопределить ее метод OnPaint
 //и в нем закрашивать нужную облаcть цветом с alpha-составляющей:
 protected override void OnPaint(PaintEventArgs e)
 {
  e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(100, Color.Green)),
   0, 0, Width, Height);
 }
 //При перемещении такой 'прозрачной' панели (например, при установке свойства Control.Location)
 //можно заметить, что  она, перемещаясь на новое место, остается с тем же background'ом,
 //что и на прежнем месте. Так происходит потому, что низлежащие окна не перерисовываются
 //в тех новых координатах, в которых находится наша Panel после перемещения, поэтому их нужно заставить обновиться:
 protected override void OnMove(EventArgs e)
 {
  if (Parent != null)
   Parent.Invalidate(Bounds, true);
 }
}

Вот форма-пример, демонстрирующая возможности рассмотренной выше
TransparentLabel:
Код:
class TransparentPanelDemo: Form
{
 TransparentPanel panel;
 public TransparentPanelDemo()
 {
  panel = new TransparentPanel();
  panel.Size = new Size(50, 50);
  Button btMove1 = new Button();
  btMove1.Text = "Move 1";
  btMove1.Click += new EventHandler(OnButton1Click);
  Button btMove2 = new Button();
  btMove2.Left = btMove1.Right * 2;
  btMove2.Text = "Move 2";
  btMove2.Click += new EventHandler(OnButton2Click);
  Label lblText = new Label();
  lblText.AutoSize = true;
  lblText.Text = "label1";
  lblText.ForeColor = Color.Red;
  lblText.Top = btMove1.Bottom;
  Controls.AddRange(new Control[] |panel, btMove1, btMove2, lblText");
 }
 void OnButton1Click(object sender, EventArgs e)
 {
  panel.Left= ((Control)sender).Right * 2;
 }
 void OnButton2Click(object sender, EventArgs e)
 {
  panel.Left = 0;
 }
 protected override void OnPaint(PaintEventArgs e)
 {
  e.Graphics.FillEllipse(Brushes.Yellow, 20, 20, 100, 100);
 }
 
 static void Main()
 {
  Application.Run(new TransparentPanelDemo());
 }
}

Обратите внимание, что TransparentPanel находится на вершине Z-порядка (она первой добавляется в коллекцию Controls формы).
« Последнее редактирование: 23-11-2007 18:17 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #9 : 10-01-2004 06:58 » 

8) Как реализовать панель, принимающую фокус?

Нужно сделать класс-наследник Panel'и, в конструкторе которого выставить в true стиль ControlStyles.Selectable. Для того, чтобы у Panel'и появлялся border, при нахождении фокуса в ней, нужно переопределить методы OnEnter и OnLostFocus и в них устанавливать/убирать бордер. В примере ниже показана такая панель, кнопка добавлена только для того, чтобы продемонстрировать использование TAB'а.

Код:
using System;
using System.Windows.Forms;
using System.Drawing;
class MyForm: Form
{
 public MyForm()
 {
  FocusedPanel focusedPanel = new FocusedPanel();
  Button button = new Button();
  button.Top = focusedPanel.Bottom;
  Controls.AddRange(new Control[]|focusedPanel, button");
 }
 static void Main()
 {
  Application.Run(new MyForm()); 
 }
}
class FocusedPanel: Panel
{
 public FocusedPanel()
 {
  SetStyle(ControlStyles.Selectable, true);
  TabStop = true;
 }
 protected override void OnEnter(EventArgs e)
 {
  base.OnEnter(e);
  BorderStyle = BorderStyle.FixedSingle;
 }
 protected override void OnLostFocus(EventArgs e)
 {
  base.OnLostFocus(e);
  BorderStyle = BorderStyle.None;
 }
}
« Последнее редактирование: 23-11-2007 18:19 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #10 : 13-01-2004 08:43 » 

9) Как создать форму с нестандартным видом?

Код:
private void Form1_Load(object sender, System.EventArgs e)
{
Point[] myArray =
{
new Point(this.Width / 2, 0),
new Point(this.Width, this.Height / 2),
new Point(this.Width * 2 / 3, this.Height),
new Point(this.Width * 1 / 3, this.Height),
new Point(0, this.Height / 2)
};
System.Drawing.Drawing2D.GraphicsPath myPath = new System.Drawing.Drawing2D.GraphicsPath();
myPath.AddPolygon(myArray);
this.Region = new Region(myPath);
}
Для изменения вида формы нужно изменить количество точек в массиве.
« Последнее редактирование: 23-11-2007 18:21 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #11 : 16-01-2004 08:20 » 

10) Как выполнить эмуляцию кликов мыши?

Можно использовать Win32 функции SendInput() или mouse_event(). В примере ниже, выполненном для простоты при помощи
mouse_event, эмулируется клик правой кнопкой мыши примерно в центре экрана:
Код:
//импортируем mouse_event(): 
[DllImport("User32.dll")]
static extern void mouse_event(MouseFlags dwFlags, int dx, int dy, int dwData, UIntPtr dwExtraInfo);

//для удобства использования создаем перечисление с необходимыми флагами (константами), которые определяют действия мыши:
[Flags]
enum MouseFlags|Move = 0x0001, LeftDown = 0x0002, LeftUp = 0x0004, RightDown = 0x0008,
 RightUp = 0x0010, Absolute = 0x8000";

//и использование - клик примерно в центре экрана(подробнее о координатах, передаваемых в mouse_event см. в MSDN):
const int x = 32000;
const int y = 32000;

mouse_event(MouseFlags.Absolute | MouseFlags.Move, x, y, 0, UIntPtr.Zero);
mouse_event(MouseFlags.Absolute | MouseFlags.RightDown, x, y, 0, UIntPtr.Zero);
mouse_event(MouseFlags.Absolute | MouseFlags.RightUp, x, y, 0, UIntPtr.Zero);
Также можно окну посылать сообщения WM_LBUTTONDOWN и WM_LBUTTONUP при помощи Win API функции SendMessage:
Код:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class MyForm: Form
{
 //Кнопка, по которой будет эмулироваться клик
 Button btDemo = new Button();
 public MyForm()
 {
  btDemo.Click += new EventHandler(OnBtDemoClick);
  Button btPerformClick = new Button();
  btPerformClick.Text = "Click!";
  btPerformClick.Click += new EventHandler(OnBtPerformClick);
  btPerformClick.Left = btDemo.Right;
  Controls.AddRange(new Control[]|btDemo, btPerformClick");
 }
 
 void OnBtDemoClick(object sender, EventArgs e)
 {
  MessageBox.Show("Button clicked");
 }
 
 void OnBtPerformClick(object sender, EventArgs e)
 {
  SendMessage(btDemo.Handle, Messages.WM_LBUTTONDOWN, MK_LBUTTON, IntPtr.Zero);
  SendMessage(btDemo.Handle, Messages.WM_LBUTTONUP, MK_LBUTTON, IntPtr.Zero);
 }
 
 static void Main()
 {
  Application.Run(new MyForm());
 }
 
 enum Messages{WM_LBUTTONDOWN = 0x0201, WM_LBUTTONUP = 0x0202};
 const int MK_LBUTTON = 0x0001;
 [DllImport("User32.dll")]
 static extern int SendMessage(IntPtr hWnd, Messages uMsg, int wParam, IntPtr lParam);
}
« Последнее редактирование: 23-11-2007 18:23 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #12 : 28-01-2004 06:15 » 

11) Продолжение

По этому адресу http://club.shelek.ru/faq/ находится "Система ЧАВО" в которой Вы можете увидить продолжение этого раздела и задать свои вопросы которые при рассмотрении (если сочтутся нужним) будут добавлены в "Систему ЧаВо"
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines