|
Mohammad Dayyan wrote: Do you know how can I do it ?
Yes I do. Thanks for asking.
Well you could always set the CheckOnClick property of a menu item to true.
|
|
|
|
|
Oh.I'm sorry for my question.
Pete O'Hanlon wrote: Well you could always set the CheckOnClick property of a menu item to true.
Thank you Pete .
But it doesn't thing that I want.
I want to put CheckBox Control (or Button control) in a menuStrip.
|
|
|
|
|
This class will do what you want - it may need some expanding to expose the checkboxes properties and events you need. You can add more controls to the flowlayoutpanel for a multicontrol control, or change the checkbox for a button or whatever.
using System;
using System.Drawing;
using System.Windows.Forms;
public class CheckBoxToolStripItem : ToolStripControlHost
{
private FlowLayoutPanel controlPanel;
private CheckBox chk = new CheckBox();
public CheckBoxToolStripItem()
: base(new FlowLayoutPanel())
{
controlPanel = (FlowLayoutPanel)base.Control;
controlPanel.BackColor = Color.Transparent;
chk.AutoSize = true;
controlPanel.Controls.Add(chk);
}
public bool Checked
{
get { return chk.Checked; }
set { chk.Checked = value; }
}
public new string Text
{
get { return chk.Text; }
set { chk.Text = value; }
}
protected override void OnSubscribeControlEvents(System.Windows.Forms.Control control)
{
base.OnSubscribeControlEvents(control);
chk.CheckedChanged += new EventHandler(CheckedChanged);
chk.TextChanged += new EventHandler(TextChanged);
}
protected override void OnUnsubscribeControlEvents(System.Windows.Forms.Control control)
{
base.OnUnsubscribeControlEvents(control);
chk.CheckStateChanged -= new EventHandler(CheckedChanged);
chk.TextChanged -= new EventHandler(TextChanged);
}
private void CheckedChanged(object sender, EventArgs e)
{
}
private new void TextChanged(object sender, EventArgs e)
{
}
} You can then create and add your item like this
CheckBoxToolStripItem chk = new CheckBoxToolStripItem();
chk.Text = "ABC";
chk.Checked = true;
menuStrip1.Items.Add(chk);
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Expect everything to be hard and then enjoy the things that come easy. (code-frog)
|
|
|
|
|
Research ToolStripControlHost.
“Time and space can be a bitch.”
–Gushie, Quantum Leap
{o,o}.oO( Looking for a great RSS reader? Try FeedBeast! )
|)””’) Built with home-grown CodeProject components!
-”-”-
|
|
|
|
|
Hi all,
I'm looking for an easy way to send message containing String data from C# application to C++ application, using the SendMessage API call.
Please refer to both sending the message and receiving it (in C++).
Thanks a lot!
Eyal.
|
|
|
|
|
are both applications exe ?
|
|
|
|
|
Yes, both Windows applications. One's GUI is written on .NET 2 C# and the second is C++ application with GUI designed using FLTK.
Thank you.
|
|
|
|
|
On the C# side, something like this maybe:
[DllImport("User32", SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
...
string ManagedString = "A string!";
IntPtr PtrToUnmanagedString = Marshal.StringToHGlobalAnsi(ManagedString);
SendMessage(hwnd, WM_SOMEMESSAGE, IntPtr.Zero, PtrToUnmanagedString);
Marshal.FreeHGlobal(PtrToUnmanagedString);
On the C++ side, handle messages in the app's message loop as usual
(kind of a big topic for here).
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
On the C++ side I have lparam of type int. How should I refer to it in order to get my string?
Thanks!
|
|
|
|
|
For the ANSI string sample I showed, something like this:
const char *pANSIstring = (const char *)lParam;
For Unicode, you could change the StringToHGlobalAnsi to
StringToHGlobalUni on the C# side, and on the C++ side, something like:
const wchar_t *pUnicodestring = (const wchar_t *)lParam;
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi Mark,
The two options you suggested doesn't work: At both cases I get 'Bad Ptr' at the C++ side (I get junk and not string).
Maybe the reason is that each one of the applications (C# and C++) uses different memory space, so passing pointers from one to another is meaningless.
Or am I missing something?
Thanks a lot,
Eyal.
|
|
|
|
|
eyalbi007 wrote: Maybe the reason is that each one of the applications (C# and C++) uses different memory space
You're absolutely right! I'm an idiot
Sorry about that - I totally spaced on the inter-process
requirement.
Looks like oobimoo showed you a solution.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
You must use the WM_COPYDATA msg
in the c# proj declare the following
[StructLayout(LayoutKind.Sequential)]
struct CopyDataStruct
{
public IntPtr dwData;
public int dataSize;
public IntPtr data;
}
enum WinMessage
{
WM_COPYDATA = 0x4A
}
class NativeAPI
{
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, WinMessage msg, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string className, string windowName);
}
and when you press a button for example
private void button1_Click(object sender, EventArgs e)
{
string s = "This is a message from sharp";
IntPtr hCWindow = NativeAPI.FindWindow("RECIEVE_DATA", "Recieve_Data");
byte[] tmpStringData = System.Text.Encoding.Unicode.GetBytes(s);
byte[] stringData = new byte[tmpStringData.Length + 2];
Array.Copy(tmpStringData, stringData, tmpStringData.Length);
stringData[stringData.Length - 2] = stringData[stringData.Length - 1] = 0;
CopyDataStruct cds = new CopyDataStruct();
cds.dwData = IntPtr.Zero;
cds.dataSize = stringData.Length;
GCHandle gch_data = GCHandle.Alloc(stringData, GCHandleType.Pinned);
cds.data = gch_data.AddrOfPinnedObject();
GCHandle gch_cds = GCHandle.Alloc(cds, GCHandleType.Pinned);
NativeAPI.SendMessage(hCWindow, WinMessage.WM_COPYDATA, this.Handle, gch_cds.AddrOfPinnedObject());
gch_data.Free();
gch_cds.Free();
}
and in the windowproc of the native app
case WM_COPYDATA:
{
PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;
MessageBox(0, (LPCTSTR)pcds->lpData, _T("CopyData message"), 0);
}
break;
The windowclass name is "RECIEVE_DATA" and the window name is "Recieve_Data" (for use with the find file in c#, although windowclass name may be null)
The default charset for my configuration is unicode. You must use ASCII encoding to get the bytes of the string in the c# code, otherwise
modified on Monday, August 25, 2008 9:39 AM
|
|
|
|
|
Hi oobimoo,
Thanks for you reply.
The C# part works fine, however, at the C++ side I can retrieve only the first character of the string ((LPCTSTR)pcds->lpData equals to "T"). I tried some other castings (string and char*) but I only get the first character.
Any ideas?
Thanks!
Eyal.
|
|
|
|
|
Your encoding at the c++ side is ascii. As i mentioned you must use the
System.Text.Encoding.ASCII.GetBytes(s) instead of the unicode that i use in my example.
|
|
|
|
|
Dear oobimoo,
Indeed, now it works. However, I'm still concerned about something: if I'm getting this correctly, the calls gch_data.Free() and gch_cds.Free() are responsible for freeing the pinned memory.
However, what if the receiving side didn't get the information before this release? Isn't it better to (somehow) release this pinned memory at the receiving side?
Consider the following chain of events:
1. Sending the message at C# application.
2. Receiving the message at the C++ application, but right before extracting the sent string:
3. Context switch at the C++ application.
4. The C# application releases the pinned memory.
5. Context switch back to the C++ application. The pinned memory is released and we can't extract the string message.
Or maybe these can't happen since SendMessage is blocking?
Thanks!
|
|
|
|
|
Your are welcome
From the msdn (WM_COPYDATA) :
"The receiving application should consider the data read-only. The lParam parameter is valid only during the processing of the message. The receiving application should not free the memory referenced by lParam. If the receiving application must access the data after SendMessage returns, it must copy the data into a local buffer. "
From the msdn (SendMessage) :
"The SendMessage function sends the specified message to a window or windows. It calls the window procedure for the specified window and does not return until the window procedure has processed the message. "
modified on Monday, August 25, 2008 1:08 PM
|
|
|
|
|
|
I am attempting to retrieve a web page through StreamReader (using HttpWebRequest and HttpWebResponse).
The issue is that the process is getting redirected to a webpage indicating that "JavaScript enabled" is not detected. Is there a parameter within the HttpWebRequest that notifies the target website that javascript is indeed enabled?
Thank you in advance.
|
|
|
|
|
You have to set the correct headers when sending the request, so that the server identifies the request as coming from a specific browser. The HTTP_USER_AGENT value contains the string that identifies the browser.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
I just found a new search engine for dot net developers. This search engine uses Google Custom Search Engine technology to provide dramatically improved search results for software developers using VB.NET, C#, ASP.NET and other .NET technologies. It searches only the best of sites having quality dot net related content.
http://tips.developersvoice.com/devsearch
I personally find it very useful. Try it yourself it is a great time saver.
Regards
Brij Kishore
TCS (INDIA)
|
|
|
|
|
Thanks For sharing nice
Vuyiswa Maseko,
Sorrow is Better than Laughter, it may Sadden your Face, but It sharpens your Understanding
VB.NET/SQL7/2000/2005
http://vuyiswamb.007ihost.com
http://Ecadre.007ihost.com
vuyiswam@tshwane.gov.za
|
|
|
|
|
Thanks for sharing. 5 from me
|
|
|
|
|
Nice search engine.Thanx
Cheers!!
Brij
|
|
|
|
|
For general programming searches (besides the CodeProject ), try Krugle[^].
Regards,
Thomas Stockwell
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
Visit my Blog
|
|
|
|