|
When I click an item and then click another item both images shows just fine, and when scrolling everything works as expected...
But when minimize/maximize the bitmaps goes away again...
Really strange...
- Anders
Money talks, but all mine ever says is "Goodbye!"
ShotKeeper, my Photo Album / Organizer Application[^]My Photos[^]
|
|
|
|
|
Definitely a refresh bug, then. Try setting ControlStyles.AllPaintingInWmPaint and ControlStyles.UserPaint to true using SetStyle in your constructor.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
|
All those list-type views are always funky when it comes to painting.
It's a bit of a hack, but how about calling Refresh (invalidates and forces an immediate update) in an override to Visible (when set to true ) or something along those lines.
Sorry for all the responses. I've just never seen this behavior before, and I've seen (and usually fix) a lot of painting bugs (the ubiquitous ListView being the usual suspect).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I just tried to make a simple listbox in my application, and making it ownerdraw, and added the code from my first post to the drawitem eventhandler...
Same problem when I minimize/maximize the app....
So when the control is refreshed, it erases everything, kinda strange...
And yeah, I have never seen this one before, and I have done lots of ownerdrawing in my time. (i actually prefer drawing in C++ )
- Anders
Money talks, but all mine ever says is "Goodbye!"
ShotKeeper, my Photo Album / Organizer Application[^]My Photos[^]
|
|
|
|
|
|
Running through some tests it seems as through XmlSerializer won't output any properties that don't have a set. What if wanted a read-only property? What am I missing?
|
|
|
|
|
This is obscurely documented in the XmlElementAttribute class documentation. You could get around it by implementing an empty set accessor and document it as a read-only property, or implement IXmlSerializable , even though you're not supposed to (I've done it in the past with no problems). It works similarily to ISerializable . There isn't documentation for it, per se, but it's not hard to figure out.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hadn't thought of using an empty set accessor, that should work for what I need. Thanks
|
|
|
|
|
I have an application that has a C# GUI that displays OpenGL images created by a C++ DLL, and what I am trying to do is elegantly control C++ variables using C# GUI menus. While I could create a public function for every menu option in the C++ DLL and call it from the appropriate C# callback, I don't want to (mostly because I'm lazy); what I would really like is to create a singleton class CGraphicsOptions to which both the C# GUI and the C++ DLL have access. If this is possible, the the C# interface could update the boolean variables therein, and the C++ code just look at them when it's time to render.
Is this possible? Or does anyone have any solutions to this type of problem?
Thanks,
Chris
|
|
|
|
|
You could make an unmanaged interface which CGraphicsOptions would implement as a COM object. Declare this interface using the appropriate GuidAttribute and InterfaceTypeAttribute . If this interface was exposed in a typelib, you could simply use tlbimp.exe (or VS.NET can do it when you add a COM reference to your project) to create an interop assembly (RCW, Runtime Callable Wrapper). That would be one way.
The reason the interface would have to be a COM interface is because casting to an interface causes the CLR to QI (QueryInterface ) for the interface. Your class's implementation of QueryInterface (ATL encapsulate all this nicely, BTW) returns a pointer to the class that implements that interface (most likely the class being QI'd) which the CLR treats as a reference to that interface.
The class wouldn't even necessarily have to be registered. So long as your C++ app's class factory creates a valid instance of it, you wouldn't even need a COM class factory (that which implements IClassFactory ), so long as the managed code could get a reference to it even if all it does is use a pointer (see the Marshal class documentation to find easy ways to QI for an interface from an IntPtr ).
Finally, there's always the ThisCall calling convention. If you export your CGraphicsOptions class in your native DLL, you need to create a class factory to create and destroy your class, but then declare managed methods using DllImportAttribute and the CallingConvention.ThisCall value for the DllImportAttribute.CallingConvention property.
So, besides exporting your class from the native DLL, also export your class factory functions:
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) LPVOID CreateGOClass();
__declspec(dllexport) void DestroyGOClass(LPVOID lpClass);
#ifdef __cplusplus
}
#endif Using the CallingConvention.ThisCall convention, you pass a pointer to your class instances as the first parameter, so each would have an IntPtr as the first param. Your methods would be declared like so:
[DllImport("mylib.dll")]
private static extern IntPtr CreateGOClass();
[DllImport("mylib.dll")]
private static extern void DestroyGOClass(IntPtr inst);
[DllImport("mylib.dll", CallingConvention=CallingConvention.ThisCall)]
private static extern void SomeMethod(IntPtr inst, int param1, int param2); For a good OO design, encapsulate all this in a singleton class that implements IDisposable . In the constructor, call CreateGOClass() to get the pointer and in Dispose call DestroyGOClass :
public sealed class GraphicsOptions : IDisposable
{
private static GraphicsOptions instance;
private IntPtr inst;
private GraphicsOptions()
{
inst = CreateGOClass();
}
private static GraphicsOptions Instance
{
get
{
if (instance == null)
lock (typeof(GraphicsOptions))
if (instance == null)
instance = new GraphicsOptions();
return instance;
}
}
public static void SomeMethod(int param1, int param2)
{
SomeMethod(Instance.inst, param1, param2);
}
void IDisposable.Dispose()
{
DestroyGOClass(inst);
GC.SuppressFinalize(this);
}
[DllImport("mylib.dll")]
private static extern IntPtr CreateGOClass();
[DllImport("mylib.dll")]
private static extern void DestroyGOClass(IntPtr inst);
[DllImport("mylib.dll", CallingConvention=CallingConvention.ThisCall)]
private static extern void SomeMethod(IntPtr inst, int param1, int param2);
} Then all you have to do to call it is:
GraphicsOptions.SomeMethod(1, 2); It wouldn't have to be a singleton, though. I just did so because you mentioned something along those lines in your request for ideas.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hi everybody,
i want to make a little programm that detect (and logging) all the new launched process on my computer.
i do not know which event is fire when a new process is opened :/
if someone could help thx a lot
|
|
|
|
|
Well, there is no event fired that signals a new process has been launched. At least not a normal one.
In theory, what you could do is use the System.Management classes to subscribe to a WMI generated event, that you have to setup, that fires when the Process list changes.
...in theory...
I've never done it, so I couldn't give you all the sticky details of the WMI part of the project.
RageInTheMachine9532
|
|
|
|
|
You could also implement a system hook (see Using Hooks from C#[^]) using the WH_CBT message to no when a window is being created, but this doesn't necessarily mean a process is being started. You can P/Invoke GetWindowModuleFileName to pass the HWND (as an IntPtr ) and get the path to the module that loaded it. If you keep these in a lookup table (like a Hashtable ), then you could quickly see if the process was already loaded. If not, add it and run your "event" handler.
Otherwise Dave's idea should work, but as he said it's untested. I've used WMI events for other things, so it should work.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
thx for your replys !
i found a possible WMI event :
Win32_ProcessStartTrace
The Win32_ProcessStartTrace event WMI class indicates that a new process has started.
but i don't know how to use WMI event, if you have an example ?
thx a lot
|
|
|
|
|
You're on the right track with that. The only problem I can see is that Win32_ProcessStartTrace requires Windows XP. Is this going to be a problem?
As for an example, I'd need some time to come up with one. I'm just starting to cook dinner now...
RageInTheMachine9532
|
|
|
|
|
yep the fact that it requires XP is a problem
so i'll try what ian propose =)
thx all
|
|
|
|
|
For the most basic monitoring, you can write a simple class to monitor processes:
using System;
using System.Collections;
using System.Diagnostics;
using System.Threading;
public delegate void ProcessStartedEventHandler(object sender, Process proc);
public delegate void ProcessExitedEventHandler(object sender, Process proc);
public class ProcessWatcher
{
#region Constants
private const int SCAN_INTERVAL = 250;
#endregion Constants
#region Instance Fields
private Mutex _myLock = new Mutex(false);
private Hashtable _procList = new Hashtable();
private Timer _scanTimer = null;
#endregion Instance Fields
#region Construction / Destruction
public ProcessWatcher() { }
~ ProcessWatcher()
{
Stop();
}
#endregion Construction / Destruction
#region Methods
public void Start()
{
_myLock.WaitOne();
if (_scanTimer != null)
{
_myLock.ReleaseMutex();
return;
}
_procList.Clear();
_scanTimer = new Timer(new TimerCallback(_Scan), null,
SCAN_INTERVAL, Timeout.Infinite);
_myLock.ReleaseMutex();
}
public void Stop()
{
_myLock.WaitOne();
if (null == _scanTimer)
{
_scanMutex.ReleaseMutex();
return;
}
_scanTimer.Dispose();
_scanTimer = null;
_procList.Clear();
_myLock.ReleaseMutex();
}
#endregion Methods
#region Implementation
private void _Scan(object unused)
{
_myLock.WaitOne();
_scanTimer.Change(Timeout.Infinite, Timeout.Infinite);
ProcessStartedEventHandler startListeners = ProcessStarted;
ProcessExitedEventHandler exitListeners = ProcessExited;
ArrayList list = new ArrayList();
Process cur = null;
foreach (Process proc in _procList)
{
if (!proc.HasExited) continue;
list.Add(proc.Id);
}
foreach (int id in list)
{
if (exitListeners != null)
exitListeners(this, (Process)_procList[id]));
_procList.Remove(id);
}
list.Clear();
Process[] running = Process.GetProcesses();
foreach (Process proc in running)
{
if (_procList.Contains(proc.Id)) continue;
list.Add(proc);
}
foreach (Process proc in list)
{
_procList.Add(proc.Id, proc);
if (startListeners != null)
startListeners(this, proc);
}
_scanTimer.Change(SCAN_INTERVAL, Timeout.Infinite);
_myLock.ReleaseMutex();
}
#endregion Implementation
#region Events
public event ProcessStartedEventHandler ProcessStarted;
public event ProcessExitedEventHandler ProcessExited;
#endregion Events
}
With the above, you can add handlers to the ProcessStarted and ProcessExited events to do whatever you wish.
The class is very basic and just off the top of my head. It may have unforseen issues so be cautious! It should be fairly thread-safe, with the _myLock.WaitOne and _myLock.ReleaseMutex calls to lock and unlock access to the important bits, but you may want to look for deadlock conditions.
You may need to adjust the SCAN_INTERVAL to better suit your needs, though I don't recommend really small intervals.
All you need to do is write your particular ProcessStarted and ProcessExited handlers; create an instance field of the class; add the hanlers to the appropriate events; and call Start to begin monitoring. The destructor will automatically call Stop for you.
Enjoy!
|
|
|
|
|
Look at PsSetCreateProcessNotifyRoutine()...
.............................
There's nothing like the sound of incoming rifle and mortar rounds to cure the blues. No matter how down you are, you take an active and immediate interest in life.
Fiat justitia, et ruat cælum
|
|
|
|
|
Does anyone know how to get Graphics.MeasureString to take into account whitespace (spaces and tabs namely) at the ends of strings? I tried feeding it a StringFormat object with the Trimming property set to StringTrimming.None but no dice. What am I missing?
|
|
|
|
|
If you read the documentation for the StringFormat.Trimming property, you'll see that it controls how strings are trimmed if they lay outside of the clipping region. It has nothing to do with trimming the whitespace on strings.
See the StringFormat.SetMeasurableCharacterRanges to specify that whitespace characters should be included when measuring.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.FitBlackBox
top secret
|
|
|
|
|
Thanks ya'll! Works like a charm!
|
|
|
|
|
I have a situation where I wanted to expose the properties of a constituent control(TextBox in this case) of my user control in the property grid. I found this to be very simple by just making a public property for my TextBox and works fine. The problem is that it doesnt write the changes of the TextBox state to the code file. If I expose they properties of the TextBox directly off the user control it does save them to the code file. I guess my question is would be: Do I have to expose every property of the constituent control on the user control to get it to generate the code or is there a work around. Someone please point me in the right direction
|
|
|
|
|
The code is generated to get/set properties on your class - the container class in this case. It would set your property to whatever text you use. When the code is executed, your property is set at runtime which sets the property on the TextBox . If you're looking for a way to control the code generation so that setting your property actually serializes the code so that the child TextBox is set, you're not going to find an easy one and I'm not sure it's even possible since VS.NET (or any designer, like SharpDeveloper) is what provides the code serialization implementation.
As far as exposing all the properties of a child control, you need to decide what you want to expose to the user. The whole idea of a complex container control is to encapsulate other controls as you require. If you end up exposing all the properties of a child control, then what's the point of encapsulating it in the first place?
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|