An unexpected continuation of
this post (honestly did not expect a resonance), so part 2 of hardcore tricks, in which we will discuss a little about the other, will wait.
So, in a nutshell, what has changed: added a control and a test application for WindowsForms, the WPF variant has changed a bit, refactoring and brushing, threadsafe has been added and the control can now be resized normally (included in the samples, but I do not advise deploying to full screen - this is really scary). Thanks comrades who pointed out the errors and shortcomings and now the project is proudly 0.5 beta. You can immediately go for the update on
razorgdipainter.codeplex.com/ , who are interested in the details please under the cat.
It will be a question of WinForms use case. Almost all control:
private readonly HandleRef hDCRef; private readonly Graphics hDCGraphics; private readonly RazorPainter RP; public Bitmap RazorBMP { get; private set; } public Graphics RazorGFX { get; private set; } public RazorPainterWFCtl() { InitializeComponent(); this.MinimumSize = new Size(1, 1); SetStyle(ControlStyles.DoubleBuffer, false); SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.Opaque, true); hDCGraphics = CreateGraphics(); hDCRef = new HandleRef(hDCGraphics, hDCGraphics.GetHdc()); RP = new RazorPainter(); RazorBMP = new Bitmap(Width, Height, PixelFormat.Format32bppArgb); RazorGFX = Graphics.FromImage(RazorBMP); this.Resize += (sender, args) => { lock (this) { if (RazorGFX != null) RazorGFX.Dispose(); if (RazorBMP != null) RazorBMP.Dispose(); RazorBMP = new Bitmap(Width, Height, PixelFormat.Format32bppArgb); RazorGFX = Graphics.FromImage(RazorBMP); } }; } public void RazorPaint() { RP.Paint(hDCRef, RazorBMP); }
As promised, the code is as simple as a boot. The transfer of GFX and BMP from the code of the test application to the code of the control immediately attracts attention. Thanks,
alexanderzaytsev , it’s calmer on the soul - it will be more difficult for the front-end programmer to create something indecent with them, and it is easier to work with the resize control.
Another noteworthy lock () in the resize code. As I already mentioned, one of the main advantages of the library is thread independent. We can ignore the UI Thread, and draw on the control from any stream, at least from three different at the same time. We do not want anyone to try to draw on the bitmap, which is currently being recreated due to resize?
Appropriately, the frontend code of the windowed application also changed a bit:
private void Render() { lock(razorPainterWFCtl1) { razorPainterWFCtl1.RazorGFX.Clear((drawred = !drawred) ? Color.Red : Color.Blue); razorPainterWFCtl1.RazorGFX.DrawString("habr.ru", this.Font, Brushes.Azure,10,10); razorPainterWFCtl1.RazorPaint(); } }
Another lock (), but we can be sure that no one can draw and resize at the same time.
In the WPF-version of almost the same changes. This implementation of threadsafe is of course clumsy, but it is good for demo test applications.
In WF, when the window is closed, Exception has time to slip through - just change the render cycle, because:
renderthread = new Thread(() => { while (true) Render(); });
This is really a stupid idea for production.
It would be possible to use a control from the WF option as a child control in the WPF version, but something tells me that it is better to separate WPF and WF branches, because with the further development there may be usage patterns that are unique to each of the architectures. But maybe I’m just scaring myself and in the future the branches will merge.
')
Use on health under the MIT-license, i.e. in any way for any purpose. Who has a desire - connect to the development of the library on
CodePlex .
UPD : Habra comrades
sintez and
nile1 convinced to do
with a reservation on the test form // better practice is Monitor.TryEnter () pattern,
Indeed, and not very complicated, and it became more correct. I updated the codex on the codep, released 0.6 beta, thanks to everyone who wrote it.