I want to create a custom messagebox
but i want use the custom icons and custom sound in during show messagebox
how do I create this Messagebox??
I no want to use the shell32.dll and user32.dll
a messagebox the same as windows 7 for windows xp
I used a simple dialog with a static method ShowCustomButtonsDialog. I placed a text label in the top left corner and changed border style to Dialog. Method simply returns button index or -1.
public partial class CustomButtonsDialog : Form
{
private const int ButtonHeight = 24;
private const int ButtonPadding = 6;
private const int ButtonInnerPadding = 5;
private const int MaxFormWidth = 700;
private int buttonIndex = -1;
public int ButtonIndex
{
get { return buttonIndex; }
private set { buttonIndex = value; }
}
public static int ShowCustomButtonsDialog(string text, string title, params string[] buttonsText)
{
var dlg = new CustomButtonsDialog(text, title, buttonsText.ToList());
dlg.ShowDialog();
return dlg.ButtonIndex;
}
public static int ShowCustomButtonsDialog(string text, string title, List<string> buttonsText)
{
var dlg = new CustomButtonsDialog(text, title, buttonsText);
dlg.ShowDialog();
return dlg.ButtonIndex;
}
public CustomButtonsDialog()
{
InitializeComponent();
}
private CustomButtonsDialog(string text, string title, List<string> buttonsText)
{
InitializeComponent();
Text = title;
labelText.Text = text;
// добавить кнопки
var formWidth = ClientSize.Width;
List<int> buttonWidths;
using (var gr = CreateGraphics())
{
buttonWidths = buttonsText.Select(b => (int)gr.MeasureString(b, Font).Width + 2 * ButtonInnerPadding).ToList();
}
var totalButtonWd = buttonWidths.Sum() + (buttonWidths.Count - 1) * ButtonPadding;
if (totalButtonWd > formWidth)
{
if (totalButtonWd <= MaxFormWidth)
Width = Width - ClientSize.Width + totalButtonWd + ButtonPadding * 2;
else
{// trim some buttons
Width = Width - ClientSize.Width + MaxFormWidth;
totalButtonWd = ClientSize.Width - ButtonPadding * 2;
var avgWidth = (totalButtonWd - (buttonsText.Count - 1) * ButtonPadding) / buttonsText.Count;
var sumThins = buttonWidths.Sum(w => w <= avgWidth ? w : 0);
var countThins = buttonWidths.Count(w => w <= avgWidth);
var countFat = buttonsText.Count - countThins;
var spareRoom = totalButtonWd - sumThins;
var fatWidth = (countThins == 0) || (countFat == 0)
? avgWidth
: (spareRoom - (countThins - 1)*ButtonPadding)/countFat;
for (var i = 0; i < buttonWidths.Count; i++)
if (buttonWidths[i] > avgWidth) buttonWidths[i] = fatWidth;
}
}
// buttons' Y-coords and height
labelText.MaximumSize = new Size(totalButtonWd,
labelText.MaximumSize.Height);
var buttonTop = labelText.Bottom + ButtonPadding;
var formHeight = buttonTop + ButtonHeight + ButtonPadding;
Height = Height - ClientSize.Height + formHeight;
// do make buttons
var buttonLeft = ButtonPadding;
var tag = 0;
for (var i = 0; i < buttonWidths.Count; i++)
{
var button = new Button
{
Parent = this,
Width = buttonWidths[i],
Height = ButtonHeight,
Left = buttonLeft,
Top = buttonTop,
Text = buttonsText[i],
Tag = tag++
};
button.Click += ButtonClick;
buttonLeft = button.Right + ButtonPadding;
Controls.Add(button);
}
}
private void ButtonClick(object sender, EventArgs e)
{
ButtonIndex = (int) ((Button) sender).Tag;
Close();
}
}
Easiest way would be to create your own MessageBox window from scratch. If you are looking for hooks to default windows MessageBox you need to consider that later you can run into problems like compatibility with other Windows operating systems.
Here are couple of samples how to create your own MessageBox:
Creating A Custom Message Box
A Custom Message Box
Custom Message Box
That will give you an idea about logic and how to start writing your own custom MessageBox.
Related
I have FlowLayoutPanel with
AutoScroll = True
FlowDirection = LeftToRight
WrapContents = True
Added controls dynamically have same Width but AutoSize in Height. So the panel will be like this, which has vertical spaces between items. As the height of row managed by the greatest height of controls. So I want to remove these unneeded spaces, and the final result will be like this.
If there's no way to do it with FlowLayoutPanel, What's the proper idea to done it perfectly ?
Its a matrix and should be treated like a matrix.
my opinion is that Panel is more appropriate than a FlowLayoutpanel here.
please see my suggestion and output to achieve such a behavior.
clarification: this code needs improvements to be adapted to all possible cases but you can learn from it the basic idea how to deal with such problem.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Example();
}
// space beetween controls (top and right)
public int MarginSpace = 8;
// first element location
public Point StartPoint = new Point(10, 10);
private void Example()
{
var fixesWidth = 70;
List<Label> randomLables = new List<Label>();
Random rand = new Random();
// generate lables with random heights
for (int i = 1; i < 10; i++)
{
Label lr = new Label();
var randheight = rand.Next(60, 120);
lr.Size = new Size(fixesWidth, randheight);
lr.Text = i.ToString();
lr.BackColor = Color.Black;
lr.ForeColor = Color.White;
randomLables.Add(lr);
}
// check how many elements in one "column" (possible also to add right+left margin)
var cols = panel1.Width / fixesWidth;
// create matrix object to get locations of each label
MyMatrix m = new MyMatrix(cols, randomLables.Count, 15, 70, StartPoint);
m.SetMatrix(randomLables);
int counter = 0;
// pupulate all lables with the points from MyMatrix object
foreach (Point p in m.pointsMatrix)
{
randomLables[counter].Location = p;
panel1.Controls.Add(randomLables[counter]);
counter++;
}
}
}
class MyMatrix
{
private int Rows;
private int TotalElements;
private int Cols;
private int Margin;
private int ElementWidth;
private Point StartPoint;
public MyMatrix(int cols, int totalelements, int margin, int elementwidth, Point startingpoint)
{
this.Cols = cols;
this.TotalElements = totalelements;
this.Margin = margin;
this.ElementWidth = elementwidth;
this.StartPoint = startingpoint;
// calculate number of rows
Rows = totalelements / cols;
}
public List<Point> pointsMatrix = new List<Point>();
int cellCounter = 0;
public void SetMatrix(List<Label> Labels)
{
for (int i = 0; i < Rows; i++)
{
for (int j = 0; j < Cols; j++)
{
var x = StartPoint.X + j * (Margin + ElementWidth);
var y = StartPoint.Y;
if (cellCounter >= Cols)
{
// find the parallel cell in the row above
y = pointsMatrix[cellCounter - Cols].Y + Labels[cellCounter - Cols].Height + Margin;
}
else
{
// do nothing it is first row
}
Point p = new Point(x, y);
pointsMatrix.Add(p);
cellCounter += 1;
}
}
}
}
Output:
I am trying to make a simple five in a row (gomoku) game for two players using windows forms and c#. I put a picturebox with a picture and stretched it out on the form. Now I want to put labels at all the intersections on the picture board so a user can click them and change their background color to black or white.
How can I make the labels created clickable on the form?
public partial class Form1 : Form
{
int labelCount = 0;
int iteration = 0;
public Form1()
{
InitializeComponent();
Label[] board = new Label[361];
for (int i = 0; i < 361; i++)
{
board[i] = new Label
{
Name = "label" + i,
Height = 55,
Width = 55,
MinimumSize = new Size(55, 55),
Text = "label " + i
};
}
int x = 0;
int y = 0;
foreach (var Label in board)
{
if (x >= 580)
{
x = 0;
y = y + Label.Height + 55;
}
Label.Location = new Point(x, y);
this.Controls.Add(Label);
x += Label.Width;
}
}
}
Should I make a one-dimensional [361] or two-dimensional array[{A,1}, {A,2}....{D,1}] to easily check for a winner? How can I connect it to the created labels so the array data corresponds to the objects on the board?
Well Sorry If don`t understand your question. For the Q.1 to add 361 labels you can try the code below. I hope it will help you.
public int x = 0;
public int y = 0;
private Label[] moku = new Label[361];
private void Form1_Load(object sender, EventArgs e)
{
try
{
for (int i = 0; i < 361; i++)
{
moku[i] = new Label();
moku[i].Parent = pictureBox1;//make the picturebox parent
moku[i].Location = new Point(x, y);
moku[i].Text = "O";
moku[i].Name = "moku" + i;
moku[i].BackColor = Color.Transparent;
pictureBox1.Controls.Add(moku[i]);
y += 55;
if (y >= 361) { x += 55; y = 0; x+=55; }
}
}catch(Exception er)
{
MessageBox.Show(er.ToString());
}
}
I prefer using a 2D array because it's easier if you want to check the surrounding boxes.
Form design:
Full source:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication6
{
public enum Player
{
Empty = 0,
White,
Black
}
public partial class Form1 : Form
{
// initialize board of 5x5
private Player[,] board = new Player[5, 5];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
DrawBoard();
}
private void DrawBoard()
{
for (var i = 0; i <= board.GetUpperBound(0); i++)
{
for (var j = 0; j <= board.GetUpperBound(1); j++)
{
// for name and text
var name = string.Format("{0}, {1}", i, j);
var label = new Label()
{
Name = name, // name of label
Size = new Size(55, 55),
BorderStyle = BorderStyle.FixedSingle,
Location = new Point(i * 55, j * 55), // location depends on iteration
Text = name
};
label.Click += ClickLabel; // subscribe the Click event handler
pictureBox1.Controls.Add(label); // add label to a container
}
}
}
// this event handler will handle all the labels click event
private void ClickLabel(object sender, EventArgs e)
{
var label = (Label)sender; // this is the label that you click
var x = Convert.ToInt32(label.Name.Split(',')[0]);
var y = Convert.ToInt32(label.Name.Split(',')[1]);
// change the color
if (radPlayerBlack.Checked)
{
// Player Black
label.ForeColor = Color.White;
label.BackColor = Color.Black;
board[x, y] = Player.Black;
}
else
{
// Player White
label.ForeColor = Color.Black;
label.BackColor = Color.White;
board[x, y] = Player.White;
}
}
}
}
You can check the value of the 2D array for black or white. Here's the value when I QuickWatch it in Visual Studio.
I developed a Winform application which has a Panel as Main Screen and two other panels on each side for previous and next video. and Two buttons which helps the Application to traverse through different videos and set it to the main panel. I have 21 videos now......
This is My code....
public void loadvideo2(int a)
{
int width = viewscreen.Width;
int height = viewscreen.Height;
int width1 = nxtpnl.Width;
int height1 = nxtpnl.Height;
int width2 = prepnl.Width;
int height2 = prepnl.Height;
video = new Video(vpath[a]);
video.Owner = viewscreen;
video.Stop();
viewscreen.Size = new Size(width, height);
video1 = new Video(vpath[a + 1]);
video1.Owner = nxtpnl;
video1.Stop();
nxtpnl.Size = new Size(width1, height1);
video2 = new Video(vpath[a - 1]);
video2.Owner = prepnl;
video2.Stop();
prepnl.Size = new Size(width2, height2);
plystpBtn.BackgroundImage = Video_Project.Properties.Resources.Style_Play_icon__1_;
plystpBtn.BackgroundImageLayout = ImageLayout.Stretch;
trckstatus.Minimum = Convert.ToInt32(video.CurrentPosition);
trckstatus.Maximum = Convert.ToInt32(video.Duration);
duration = CalculateTime(video.Duration);
playposition = "0:00:00";
posdurtrclbl.Text = playposition + "/" + duration;
b = a;
vlbl.Text = "Video" + Convert.ToString(b);
}
private void preBtn_Click(object sender, EventArgs e)
{
videono += 1;
if (videono <= vcount-1)
{
loadvideo2(videono);
}
else
MessageBox.Show("File Not Found!!!");
}
private void nxtBtn_Click(object sender, EventArgs e)
{
videono -= 1;
if (videono >= 0)
{
loadvideo2(videono);
}
else
MessageBox.Show("FIle Not Found!!!");
}
now while i am traversing through the videos by pressing buttons its working fine till the 16th video where i am getting an error message
ffmpeg.dll failed to load
can any one help me to solve this
solved it. It was probably a memory consumption issue.
public void loadvideo2(int a)
{
int width = viewscreen.Width;
int height = viewscreen.Height;
int width1 = nxtpnl.Width;
int height1 = nxtpnl.Height;
int width2 = prepnl.Width;
int height2 = prepnl.Height;
video.Dispose();
video = new Video(vpath[a]);
video.Owner = viewscreen;
video.Stop();
viewscreen.Size = new Size(width, height);
video1 = new Video(vpath[a + 1]);
video1.Owner = nxtpnl;
video1.Stop();
nxtpnl.Size = new Size(width1, height1);
video2 = new Video(vpath[a - 1]);
video2.Owner = prepnl;
video2.Stop();
prepnl.Size = new Size(width2, height2);
plystpBtn.BackgroundImage = Video_Project.Properties.Resources.Style_Play_icon__1_;
plystpBtn.BackgroundImageLayout = ImageLayout.Stretch;
trckstatus.Minimum = Convert.ToInt32(video.CurrentPosition);
trckstatus.Maximum = Convert.ToInt32(video.Duration);
duration = CalculateTime(video.Duration);
playposition = "0:00:00";
posdurtrclbl.Text = playposition + "/" + duration;
b = a;
vlbl.Text = "Video" + Convert.ToString(b);
video1.Dispose();
video2.Dispose();
}
It's my problem.
I have a few RadioButtons. If i click on first Radiobutton on form create TextBox, if click on second - create second TextBox and if i click again on first RadioButton, again one TextBox,is it possible?
Give me idea, please.
And without property visible.
There isn't much point in dynamically creating and destroying controls here. It is just a headache, ensuring the position, size and tab order is correct. Just make the text box visible if you like the choice:
private void radioButton2_CheckedChanged(object sender, EventArgs e) {
textBox1.Visible = radioButton2.Checked;
}
Set the textbox' Visible property to False in the designer.
Try something like this (this is only one of them):
TextBox t;
private void radio_CheckedChanged(object sender, System.EventArgs e)
{
if (radio.Checked) {
t = new TextBox();
t.Top = radio.Top;
t.Left = radio.Left + radio.Width;
this.Controls.Add(t);
t.Show();
} else {
if (t!=null)t.Dispose();
}
}
See Only foreach and void TextBoxes.
using System;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
class MyForm : Form
{
private const int
HeightTextBox = 40, WidthTextBox = 25, //размер textboxes
DistanceBetweenTexBoxHeight = 25, DistanceBetweenTexboxWigth = 25; //растояние между ними
private int DimentionalTextBox = 3;
private const int
RadioButtonNumbers = 3, // количество радио кнопок
DistanceBetweenRadiobutton = 50,
RadioButtonFirstGroupStartPositionX = 5,
RadioButtonSecondGroupStartPositionX = 0,
RadioButtonFirstGroupStartPositionY = 0,
RadioButtonSecondGroupStartPositionY = 0,
RadioButtonSize = 25;
public MyForm()
{
//Size of window
ClientSize = new System.Drawing.Size(7 * HeightTextBox + 8 * DistanceBetweenTexBoxHeight,
7 * WidthTextBox + 8 * DistanceBetweenTexboxWigth);
//Create RaioButton
int x = RadioButtonFirstGroupStartPositionX;
int y;
RadioButton[] DimRadioButtons = new RadioButton[RadioButtonNumbers];
for (int i = 0; i < RadioButtonNumbers; i++)
{
DimRadioButtons[i] = new RadioButton();
DimRadioButtons[i].Name = "RadioButton" + (i + 2);
DimRadioButtons[i].Text = Convert.ToString(i + 2);
DimRadioButtons[i].SetBounds(x, RadioButtonFirstGroupStartPositionY, RadioButtonSize, RadioButtonSize);
x += DistanceBetweenRadiobutton;
Controls.Add(DimRadioButtons[i]);
}
//Watch dimention
// And catch even click on RadioButton
foreach (var a in this.Controls)
{
if (a is RadioButton)
{
if (((RadioButton)a).Checked)
{
DimentionalTextBox = Convert.ToInt16(((RadioButton)a).Text);
((RadioButton)a).Click += new EventHandler(this.TextBoxes);
}
}
}
}
// Create-Delete TextBoxes
private void TextBoxes(object sender, EventArgs e)
{
RadioButton rb_click = (RadioButton)sender;
int x = RadioButtonFirstGroupStartPositionX;
int y = 30;
int dim = Convert.ToInt16(rb_click.Text);
TextBox[,] MatrixTextBoxes = new TextBox[dim, dim];
for (int i = 0; i < dim; i++)
{
for (int j = 0; j < dim; j++)
{
MatrixTextBoxes[i, j] = new TextBox();
MatrixTextBoxes[i, j].Top = rb_click.Top;
MatrixTextBoxes[i, j].Name = "MatrixTextBox" + i + j;
MatrixTextBoxes[i, j].Text = i + " " + j;
MatrixTextBoxes[i, j].SetBounds(x, y, WidthTextBox, HeightTextBox);
x += DistanceBetweenTexboxWigth;
this.Controls.Add(MatrixTextBoxes[i, j]);
MatrixTextBoxes[i, j].Show();
}
y += DistanceBetweenTexBoxHeight;
x = RadioButtonFirstGroupStartPositionX;
}
}
}
class MyClassMain : MyForm
{
public static void Main()
{
Application.Run(new MyClassMain());
}
}
my panel in my windows form application doesn't include all the buttons i asked it to. It shows only 1 button, Here is the code
private void AddAlphaButtons()
{
char alphaStart = Char.Parse("A");
char alphaEnd = Char.Parse("Z");
for (char i = alphaStart; i <= alphaEnd; i++)
{
string anchorLetter = i.ToString();
Button Buttonx = new Button();
Buttonx.Name = "button " + anchorLetter;
Buttonx.Text = anchorLetter;
Buttonx.BackColor = Color.DarkSlateBlue;
Buttonx.ForeColor = Color.GreenYellow;
Buttonx.Width = 30;
Buttonx.Height = 30;
this.panelButtons.Controls.Add(Buttonx);
//Buttonx.Click += new System.EventHandler(this.MyButton_Click);
}
}
Aren't they all going to be on the same position?
Try setting Buttonx.Location = new Point(100, 200);
(but with different points for different buttons)
You could use a FlowLayoutPanel, which would take care of the layout for you, or you need to track the locations yourself, or which could look something like this:
private void AddAlphaButtons()
{
char alphaStart = Char.Parse("A");
char alphaEnd = Char.Parse("Z");
int x = 0; // used for location info
int y = 0; // used for location info
for (char i = alphaStart; i <= alphaEnd; i++)
{
string anchorLetter = i.ToString();
Button Buttonx = new Button();
Buttonx.Name = "button " + anchorLetter;
Buttonx.Text = anchorLetter;
Buttonx.BackColor = Color.DarkSlateBlue;
Buttonx.ForeColor = Color.GreenYellow;
Buttonx.Width = 30;
Buttonx.Height = 30;
// set button location
Buttonx.Location = new Point(x, y);
x+=30;
if(x > panel1.Width - 30)
{
x = 30;
y+=30;
}
this.panelButtons.Controls.Add(Buttonx);
//Buttonx.Click += new System.EventHandler(this.MyButton_Click);
}
}