Click here to Skip to main content
15,910,411 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
See more:
Ok, here is the example.
Why XORCycleA doesn't work while XORCycleB works...
Here is quite serious riddle for an expert.
Hope you can "speak" C# and will understand my strings without additional comments :))
XOR_Paint will be invoked each time you move the dialog window and smth overlays it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;
namespace ConsoleTestApplication
{
 class Program
 {
 static void Main(string[] args)
 {
  new XOR().ShowDialog();
 }
 }
 internal class XOR : Form
 {
 [DllImport("gdi32.dll")]
 public static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc,
            int nXSrc, int nYSrc, Int32 dwRop);
 [DllImport("gdi32.dll")]
 public static extern bool TextOut(IntPtr hdc, int x, int y, string lpString, int cbString);
 const Int32 SRCCOPY = 0x00CC0020;
 const Int32 SRCAND = 0x008800C6;
 const Int32 SRCINVERT = 0x00660046; // INVERT means XOR
 public XOR()
 {
  // Bit map created once with screen data in it
  bmA = new Bitmap(s.Width, s.Height, PixelFormat.Format32bppRgb);
  Graphics gfxBMP = Graphics.FromImage(bmA);
  gfxBMP.CopyFromScreen(0, 0, 0, 0, new Size(s.Width, s.Height), CopyPixelOperation.SourceCopy);
  gfxBMP.Dispose();
  this.Paint += new PaintEventHandler(XOR_Paint);
 }
 void XOR_Paint(object sender, PaintEventArgs e)
 {
  xorCycleA();
  xorCycleB();
 }
 Bitmap bmA;
 Size s = Screen.PrimaryScreen.Bounds.Size;
 unsafe void xorCycleA()
 {
  Graphics grfxScreen = Graphics.FromHwnd(IntPtr.Zero);
  Graphics grfxBitmap = Graphics.FromImage(bmA);
  bmA.Save(@"c:\before_xorA.bmp", ImageFormat.Bmp);
  IntPtr hdcBitmap = grfxBitmap.GetHdc();
  IntPtr hdcScreen = grfxScreen.GetHdc();
  // without any changes just copy screen data with XOR
  BitBlt(hdcBitmap, 0, 0, bmA.Width, bmA.Height, hdcScreen, 0, 0, SRCINVERT);
  grfxScreen.ReleaseHdc(hdcScreen);
  grfxBitmap.ReleaseHdc(hdcBitmap);
  grfxScreen.Dispose();
  grfxBitmap.Dispose();
  bmA.Save(@"c:\after_xorA.bmp", ImageFormat.Bmp);
 }
 Bitmap bmB;
 unsafe void xorCycleB()
 {
  Graphics grfxScreen = Graphics.FromHwnd(IntPtr.Zero);
  bmB = new Bitmap((int)grfxScreen.VisibleClipBounds.Width,
    (int)grfxScreen.VisibleClipBounds.Height, grfxScreen);
  Graphics grfxBitmap = Graphics.FromImage(bmB);
  bmB.Save(@"c:\before_xorB.bmp", ImageFormat.Bmp);
  IntPtr hdcBitmap = grfxBitmap.GetHdc();
  IntPtr hdcScreen = grfxScreen.GetHdc();
  BitBlt(hdcBitmap, 0, 0, bmB.Width, bmB.Height, hdcScreen, 0, 0, SRCCOPY);
  TextOut(hdcBitmap, 100, 100, "Hi, I'm here", 12);
  // comment BitBlt to make sure the bitmap contains screen data and the string on it inside after_xorB.bmp
  BitBlt(hdcBitmap, 0, 0, bmB.Width, bmB.Height, hdcScreen, 0, 0, SRCINVERT);
  grfxScreen.ReleaseHdc(hdcScreen);
  grfxBitmap.ReleaseHdc(hdcBitmap);
  grfxScreen.Dispose();
  grfxBitmap.Dispose();
  bmB.Save(@"c:\after_xorB.bmp", ImageFormat.Bmp);
 }
 }
}
Posted
Comments
Richard MacCutchan 9-Jul-11 9:16am    
The expression "doesn't work" is really no help to anyone. You need to explain in detail what you are trying to do, what results you see and what results you expect. Remember, we cannot see your screen so have no idea what the output may look like.
RobbKirk 9-Jul-11 11:44am    
Richard, I don't want to explain to everyone. I need only assistance of GDI expert. Trust me, for those who know BitBlt there is no problem to understand what is this code about.
thatraja 9-Jul-11 12:43pm    
Actually, he was asked about the details of the code. Because we have no idea about your code & also don't know what do you want because no clue(Here you just pasted the code with out any clue) so he replied you for further details. Also read again the last line of his comment "Remember, we cannot see your screen so have no idea what the output may look like."
Sergey Alexandrovich Kryukov 9-Jul-11 14:17pm    
I agree with Richard. You make your question answerable in principle, but practically not. I could build a project based on your code and try it. But before I do, I always hope to catch a problem from a first glance. In 95% it works. I hope to see exception dump and indication of exceptions marked in the comments of source code. It makes immediate resolution very likely.

Only if I cannot see the problem I would consider building a project and testing. It covers almost all situation; and I offer the resolution. I already helped tens or hundreds of members this way.

However, as I consider my time very valuable, I look at one more thing: does OP ***deserve*** this? An inquirer who is reluctant to provide information I mentioned above (or other helpful information when there are no exceptions) does not pass this simple test. What would make me interested enough to answer to such person?

However, anyone deserves a second chance. You can use "Improve question".
--SA
RobbKirk 9-Jul-11 16:57pm    
You have two options: Yes/No
or just skip my question... no one is obliged to dig out of my stupid, idiotic and moron-made crap code...

The line
BitBlt(hdcBitmap, 0, 0, bmA.Width, bmA.Height, hdcScreen, 0, 0, SRCCOPY);

seem to be missing in version XORCycleA.

What I would think if that even though the bitmap bmA contains the image, hdcBitmap is black without initializing its content from the screen.

Well probably 10 years have elasped since last time I have used BitBlt. At that time,to help debugging, my code was made in a way that I could write directly to the screen instead of in-memory. That way, when I have some problem, I run the debugger so that it don't hide the part where I was drawing and the step through the code.

Create another file in that method and copy the content of hdcBitmap to a file to see if it does what you think.

By the way, the final result is dependent on the order of calling XORCycleA and XORCycleB and the result might differ depending on the system (XP, Vista or Windows 7). In fact, it seems to be related to animation thus the only way to have consistent result is to put a breakpoint (and then rezise the form to force a paint) and ignore the first time the code is called since the first generated result would have the form fading in...

Thus is was not so simple as copying the code... As it was a console application, we had to add reference to make it work (then allows unsafe code) and then understand the subtilities...

Once the SRCCOPY and TextOut lines are added to XORCycleA, both function give essentially the same "after" image (except initially because of the fading of the form in progress that affect the first generated image).
 
Share this answer
 
Comments
RobbKirk 9-Jul-11 15:23pm    
>What I would think if that even though the bitmap bmA contains the image, hdcBitmap is black without initializing its content from the screen.

see the constructor

>Well probably 10 years have elasped since last time I have used BitBlt.
Thus is was not so simple as copying the code... As it was a console application, we had to add reference to make it work (then allows unsafe code) and then understand the subtilities...

writing here should be even harder for you, please, don't do it. it's not mandatory... relax.
thnx anyways.
If it does not works and you cannot find why (I guees you need cycle A to see difference from last save and cycle B from to output annotated changes), you might try to somehow manually copy the bitmap into the device context...

Do you need to also call SelectObject()?

If that still does not works then you coucl use P/Invoke or a C++/CLI to do it with something that works. Since you already have unsafe code, then it should not matters much to add a C++/CLI that would uses working C++ code.
 
Share this answer
 
Comments
RobbKirk 9-Jul-11 16:53pm    
SelectObject needs to be used when want to draw smth.
When Blitting context from one to another no need to Select... because it's just bitmap context.. like a paper for writing, and it is the already saved Bitmap.
Select is used when you use Graphics - methods to draw, that will be applied to "paper" (context).
But in my case XORing duznt work when bitmap is taken from previous capturing.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900