|
|
|
The System.Drawing.Point Class has really a lot of missing Features. It has no TypeConverter and no support for operators like + and -. This is really weak.
Is there any possibility to fix that issue? Sure... I could write an own Point class but that one won't be compatible with all the (drawing-)functions like DrawPoly and I don't want to write some ugly conversion code.
|
|
|
|
|
|
Actually you seem to be clueless...
[Serializable, StructLayout(LayoutKind.Sequential), TypeConverter(typeof(PointConverter)), ComVisible(true)]
public struct Point
{
public static readonly Point Empty;
public Point(int x, int y);
public Point(Size sz);
public Point(int dw);
public bool IsEmpty { get; }
public int X { get; set; }
public int Y { get; set; }
public static implicit operator PointF(Point p);
public static explicit operator Size(Point p);
public static Point operator +(Point pt, Size sz);
public static Point operator -(Point pt, Size sz);
public static bool operator ==(Point left, Point right);
public static bool operator !=(Point left, Point right);
public static Point Ceiling(PointF value);
public static Point Truncate(PointF value);
public static Point Round(PointF value);
public override bool Equals(object obj);
public override int GetHashCode();
public void Offset(int dx, int dy);
public override string ToString();
}
top secret Download xacc-ide 0.0.3 now! See some screenshots
|
|
|
|
|
Yes indeed, and everything is explained on MSDN. All my fault
Actually I tried to convert a string into a point and also tried to sumarize two Points. Well, at least now I know how it works
|
|
|
|
|
in the Button1_Click I need to make the 1st column saved as readonly.
How can I do this?
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Xml.Xsl;
using System.Xml;
namespace PDM.excel
{
///
/// Summary description for WebForm3.
///
public class WebForm3 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.DataGrid DataGrid1;
public SqlConnection conDB = new SqlConnection();
static public string[] LanguageStr =
{
"English","French","Spanish"};
static public string[] DropDownListStr =
{
"Language_DropDownList"};
protected System.Web.UI.WebControls.DropDownList Language_DropDownList;
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Button Button1;
static public string[][] AddStrArray =
{
LanguageStr};
private void Fill_DropDownList()
{
for (int i = 0; i < DropDownListStr.Length; i++)
{
string CtrlName= DropDownListStr[i];
DropDownList MyList = (DropDownList)Page.FindControl(CtrlName);
// Populate all the checkboxes
string[] ToPopulate = AddStrArray[i];
for (int j = 0; j < ToPopulate.Length; j++)
{
MyList.Items.Add(new ListItem(ToPopulate[j], j.ToString()));
}
}
}
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
if(!Page.IsPostBack)
{
Fill_DropDownList();
}
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.Language_DropDownList.SelectedIndexChanged += new System.EventHandler(this.Language_DropDownList_SelectedIndexChanged);
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
public DataSet DataToExcel = new DataSet();
private void Language_DropDownList_SelectedIndexChanged(object sender, System.EventArgs e)
{
int getSelectedIndex = Language_DropDownList.SelectedIndex+1;
conDB.ConnectionString = "data source=10.195.17.7;database=devnew;uid=bounaajak;pwd=ehsfirst;packet size=4096";
SqlDataAdapter da = new SqlDataAdapter("Select string_id, string from pdm_translations where language_id = 1 and string_id not in (select string_id from pdm_translations where language_id = " + getSelectedIndex.ToString() + ") ", conDB);
da.Fill(DataToExcel, "DataToExcel");
Session["Tabla"] = Language_DropDownList.SelectedItem.Text;
DataToExcel.WriteXml(Server.MapPath(Session["Tabla"] + ".xml"));
DataGrid1.DataSource = DataToExcel;
DataGrid1.DataBind();
Language_DropDownList.Visible = false;
}
private void Button1_Click(object sender, System.EventArgs e)
{
Response.ContentType = "application/vnd.ms-excel";
Response.Charset = "";
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath(Session["Tabla"] + ".xml"));
XmlDataDocument xdd = new XmlDataDocument(ds);
XslTransform xt = new XslTransform();
xt.Load(Server.MapPath("Excel.xsl"));
xt.Transform(xdd, null, Response.OutputStream);
Response.End();
}
}
}
|
|
|
|
|
in the Button1_Click I need to make the 1st column saved as readonly.
How can I do this?
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Xml.Xsl;
using System.Xml;
namespace PDM.excel
{
///
/// Summary description for WebForm3.
///
public class WebForm3 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.DataGrid DataGrid1;
public SqlConnection conDB = new SqlConnection();
static public string[] LanguageStr =
{
"English","French","Spanish"};
static public string[] DropDownListStr =
{
"Language_DropDownList"};
protected System.Web.UI.WebControls.DropDownList Language_DropDownList;
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Button Button1;
static public string[][] AddStrArray =
{
LanguageStr};
private void Fill_DropDownList()
{
for (int i = 0; i < DropDownListStr.Length; i++)
{
string CtrlName= DropDownListStr[i];
DropDownList MyList = (DropDownList)Page.FindControl(CtrlName);
// Populate all the checkboxes
string[] ToPopulate = AddStrArray[i];
for (int j = 0; j < ToPopulate.Length; j++)
{
MyList.Items.Add(new ListItem(ToPopulate[j], j.ToString()));
}
}
}
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
if(!Page.IsPostBack)
{
Fill_DropDownList();
}
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.Language_DropDownList.SelectedIndexChanged += new System.EventHandler(this.Language_DropDownList_SelectedIndexChanged);
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
public DataSet DataToExcel = new DataSet();
private void Language_DropDownList_SelectedIndexChanged(object sender, System.EventArgs e)
{
int getSelectedIndex = Language_DropDownList.SelectedIndex+1;
conDB.ConnectionString = "data source=10.195.17.7;database=devnew;uid=bounaajak;pwd=ehsfirst;packet size=4096";
SqlDataAdapter da = new SqlDataAdapter("Select string_id, string from pdm_translations where language_id = 1 and string_id not in (select string_id from pdm_translations where language_id = " + getSelectedIndex.ToString() + ") ", conDB);
da.Fill(DataToExcel, "DataToExcel");
Session["Tabla"] = Language_DropDownList.SelectedItem.Text;
DataToExcel.WriteXml(Server.MapPath(Session["Tabla"] + ".xml"));
DataGrid1.DataSource = DataToExcel;
DataGrid1.DataBind();
Language_DropDownList.Visible = false;
}
private void Button1_Click(object sender, System.EventArgs e)
{
Response.ContentType = "application/vnd.ms-excel";
Response.Charset = "";
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath(Session["Tabla"] + ".xml"));
XmlDataDocument xdd = new XmlDataDocument(ds);
XslTransform xt = new XslTransform();
xt.Load(Server.MapPath("Excel.xsl"));
xt.Transform(xdd, null, Response.OutputStream);
Response.End();
}
}
}
|
|
|
|
|
First I should mention that I'm not sure if it can be done since I've never tried. Second, creating readonly columns in excel is an excel document specific action which means you will most likely have to use office automation to achieve what you want. In case you're not familiar with it, office automation provides a way to programmatically control MS Office applications.
Best Regards.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
I'm trying to determine the best way to establish the address offset in array.
Example in C:
// **** begin code snippet
unsigned char data[256]; // with some kind of data in it.
unsigned char *result;
result = data+0x20; // copies data at offset address of 0x20
// **** end code snippet
Now how I need to set that up in C#? (correct me if I'm wrong!)
// **** begin code snippet
byte[] data = new Byte[256]; // with some kind of data in it.
byte[] result;
result = data+0x20; // copies data at offset address of 0x20
// **** end code snippet
|
|
|
|
|
I don't believe you can do pointer arithmetic in C#, but arrays are actually classes in C#, and they have a copy method. Obviously, then you end up with two arrays, not a smaller array into the same data, as you would with the C++ code here.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
You can do pointer arithmetic if you use an unsafe block (and tell the compiler to allow it with the /unsafe command-line switch) and pin data n memory:
using System;
class Test
{
unsafe static void Main()
{
byte[] data = new byte[256];
for (int i=0; i<data.Length; i++)
data[i] = (byte)i;
byte[] result = new byte[data.Length - 0x20];
fixed (byte *b1 = &data[0x20])
fixed (byte *b2 = &result[0])
*b2 = *b1;
Console.WriteLine(result[0]);
}
} See my reply to him if you're interesting in what you already recommend: Array.Copy .
What is confusing is that he says "copy" but is only referencing data in his example.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Actually, neither example is copying data. You're pointing result at the element at offset 0x20 (32) from data in the native code.
As Christian said, you can use Array.Copy if you actually want to copy data:
byte[] data = new byte[256];
byte[] result = new byte[256 - 32];
Array.Copy(data, 0x20 , result, 0, 256 - 32); In your native code, if you want to copy - no reference - the data, you need to do something like so:
malloc(&result, 256 - 30);
memcpy(result, data + 0x20 , 256 - 32); See my reply to Christian for how you can do pointer arithmetic (which is, remember, just referencing - not copying) if you're interested.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I need to indicate on a windows form that it's not in normal mode, but is in template mode. I was thinking one neat way to do it would be to put a diagonal 'watermark' text saying TEMPLATE across the form that doesn't interfere with the controls at all.
Kinda like the TOP SECRET or CONFIDENTIAL you see stamped on pages in movies.
I'm not very up on the graphics and drawing elements of windows forms, but I attempted to draw text over the form to no avail, I used the form.CreatGraphics method to get a graphics object but it seems to always draw behind the panels and controls which makes sense I think since it's a graphics object of the underlying form. I guess I need one that is for the whole window in general?!?
I need something that draws right overtop of everything but doesn't interfere with the normal control usage and is only present for that form window (i.e. if a user goes to their desktop or something it is not still there).
I'm guessing this isn't possible, but I thought I would check with the experts here before giving up entirely on the idea.
|
|
|
|
|
If it is possible, it's not trivial. You would probably have to determine the position of each of the controls and draw pieces of your image on the individual controls according to the place of the entire image over the form.
Say that you call CreateGraphics and get the graphics context for the form. You then create an offscreen context on which you draw your diagonal text. Then you iterate through your controls and find their position and size on the form. Then you clip the region of the offscreen graphics containing your text according to the position and size and then draw it on the control from which you got those dimensions. Although, I think that if you override the drawing of each individual control, you may cause your controls to function improperly. Anyhow, though it's probably possible I'm fairly certain it is not worth the effort.
Best Regards.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
Yikes! Wow, no, definitely not worth the effort! Thank you for confirming that. I'll stick with something simpler I guess.
Cheers!
|
|
|
|
|
What the reply said isn't true. The controls are drawn on top of the form, so the form just needs to draw a watermark and that's it.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
class Test : Form
{
static void Main()
{
Application.Run(new Test());
}
StringFormat format;
Font watermarkFont;
Test()
{
format = StringFormat.GenericDefault;
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
watermarkFont = new Font(Font.FontFamily, 30f, FontStyle.Bold);
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer|
ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
RichTextBox rtb = new RichTextBox();
Controls.Add(rtb);
rtb.Location = new Point(8, 8);
rtb.Size = new Size(100, 60);
Text = "Watermark Example";
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.DrawString("Watermark", watermarkFont, SystemBrushes.ControlDark,
new PointF(Width / 2f, Height / 2f), format);
}
} Compile and resize the form and you'll see. This is true of owner-drawing. Child controls paint on top of their parents. It's all 2D drawing, but think of it as 3D in terms of what you draw. For efficiency, you should take the PaintEventArgs.ClipRectangle into account, though, which gives you the clipping region that you only need to draw. This is best for complex drawing, like a vector drawing program that only needs to update certain vector or raster images within the clipping region and not the entire canvas.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I've compiled your example, but the watermark still shows up behind the richtextbox control. I'm a little confused as to how you are saying you would make the watermark display on top of the richtextbox control.
Thanks.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
I was confused about his first reply and added a new answer directly to his post. See that.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
That is not true. The child controls are painted over their parent, so only the form needs to draw the watermark and you don't have to calculate which "pieces" to draw. See my reply to him at http://www.codeproject.com/script/comments/forums.asp?msg=1010209&forumid=1649#xx1010209xx[^].
Also, you never use CreateGraphics for owner-drawing unless you want your painted object to disappear when a section or all of it is invalidated. When possible, override OnPaint ; otherwise, handle the Paint event of the control you wish to paint.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I stand corrected. I guess that's what I get for not actually trying it.
Thanks.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
After re-reading this I see what you're asking, but I hope that my other post answered why you were seeing what you were seeing. Also, never use CreateGraphics to owner-draw. You need to override OnPaint and use the PaintEventArgs.Graphics otherwise whatever you draw will not be re-drawn when the region is covers (or any part of it) is invalidated.
If you want to draw over everything the easiest way is to use an invisible - except for the text - window. For this you used layered windows, which are only supported on Windows 2000 and newer. Layered windows are what allow Form.Opacity to work, which is why that property is only supported on Windows 2000 and newer. P/Invoke the SetLayeredWindowAttributes API, which you can read about in the Platform SDK.
A way that is supported on all platforms is to use a clipping region for a control that covers the entire form, like so:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
class Test : Form
{
static void Main()
{
Application.Run(new Test());
}
Test()
{
Watermark w = new Watermark();
Controls.Add(w);
w.Dock = DockStyle.Fill;
w.Font = new Font(Font.FontFamily, 48f, FontStyle.Bold);
w.ForeColor = SystemColors.ControlDark;
w.Text = "Example";
TextBox tb = new TextBox();
Controls.Add(tb);
tb.Location = new Point(8, 8);
Text = "Watermark Example";
}
}
public class Watermark : Control
{
StringFormat format;
GraphicsPath path;
Brush brush;
public Watermark()
{
SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
format = StringFormat.GenericDefault;
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
brush = new SolidBrush(ForeColor);
OnResize(EventArgs.Empty);
}
public override Color ForeColor
{
get { return base.ForeColor; }
set
{
brush = new SolidBrush(value);
base.ForeColor = value;
}
}
[DefaultValue(StringAlignment.Center)]
public StringAlignment HorizontalAlignment
{
get { return format.Alignment; }
set { format.Alignment = value; }
}
[DefaultValue(StringAlignment.Center)]
public StringAlignment VerticalAlignment
{
get { return format.LineAlignment; }
set { format.LineAlignment = value; }
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
Refresh();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
path = new GraphicsPath();
path.AddString(Text, Font.FontFamily, (int)Font.Style,
Font.Size, new PointF(Width / 2f, Height / 2f), format);
Region = new Region(path);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillPath(brush, path);
}
}
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Cool. Thanks for explaining.
The only problem you run into now is that the new watermark control may obstruct one of the underlying controls. Is there a way to pass the click on to whatever control lies behind it?
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
In a 2D world, not easily. Windows, like most other window managers in the world, simply draws controls using clipping regions. If a control is partly obstructed that portion is not drawn (controls may try to draw there, but it will only be clipped). Windows 2000 and newer does support layered windows, which you can read about if you look up SetLayeredWindowAttributes in the Platform SDK at http://msdn.microsoft.com/library[^].
So, just sending a click message to the parent form with those coordinates won't work: your control is the control at those coordinates.
The thing is, the controls underneath that control don't know that. What you'll need to do is find the control closest to the click coordinates using methods from the GraphicsPath class. When you have those coordinates, translate them as necessary (so if they're screen coordinates, be sure to call PointToClient on the Control that you want to to be clicked. These could still be the original click coordinates for the Watermark control I developed as a quick example, but you'll need to determine which control to send messages to by translating those coordinates till you get a control that's close by.
P/Invoke SendMessage and send WM_LBUTTONDOWN (0x0201; don't worry about translating this for left-handed mice; Windows does that automatically) with the client coordinates, followed by WM_LBUTTONUP (0x0202).
That should work.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
That works, but on the actual form I need it on which is incredibly complex I get an out of memory exception when I go to show one of the panels that I didn't get before.
Wierd because it works with all the other panels being shown, it's seemingly unrelated. I'll dig into it more using your example as a starting point and try to determine why I would get an out of memory error on that form.
It definitely allows text to hover over the form and not interfere with the controls.
Thank you.
[UPDATE: it works. The error was something unrelated of course! ]
|
|
|
|
|