|
Just to ensure there is no confusion. The bits I mean are the values of pixels, sorry for that term, but it's used in the BITMAP structure.
What I do mean, that if you are comparing images with true colors (24-bit color depth or more) there will be no problem, but for indexed images(16-bit, 8-bit etc) the problem of color table arise.
If all pixel values match in an indexed bitmaps that does not mean their color tables match.
I just wanted to be clearer.
|
|
|
|
|
AH ok ok, sorry I had not understood !
so i shouldn't have probleme with that.
thank you to take your time to explain me.
|
|
|
|
|
ok, i try your example, but i have a problem with :
if(memcmp(data1, data2, bytesize) == 0)
i have always windows error, i think it's because bytesize
you know how can i find the problem?
thx in advance
|
|
|
|
|
I assume that the error is a crash due to access viloation, so firstly check if either pointers are not null, this method works only with DIB bitmaps (i.e. you can't try it with bitmaps of a Client area DC or a Window DC) otherwise the pixels array is null.
If they are not null then I need to know the winodws version you use and the bitmaps dimensions and color depth to identiy the problem.
You my also try to replace the 4 with 2 in this line
DWORD bmWidthBytes = bmWidth + (4 - bmWidth % 4) * bool(bmWidth % 4);
|
|
|
|
|
Thx to help me !
MAAK wrote:
I assume that the error is a crash due to access viloation
completely !
this is what i do :
1 - I do a snapshot and save the bitmap in Clipboard
CMainFrame *pFrame = (CMainFrame*)AfxGetMainWnd();
CChildFrame *pChild = (CChildFrame *) pFrame->GetActiveFrame();
CRect WndRect;
CWnd* pMDIClientWnd = CWnd::FromHandle(pFrame->m_hWndMDIClient);
GetClientRect(WndRect);
CBitmap bitmap;
CDC *dcP;
CDC memDC;
CRect rect;
dcP = GetWindowDC();
memDC.CreateCompatibleDC(dcP);
bitmap.CreateCompatibleBitmap(dcP,WndRect.right, WndRect.bottom);
CBitmap *pOldBitmap = memDC.SelectObject(&bitmap);
memDC.BitBlt(0, 0, WndRect.right,WndRect.bottom, dcP,2 , 2, SRCCOPY);
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP, bitmap.GetSafeHandle());
CloseClipboard();
memDC.SelectObject(pOldBitmap);
2 - i want to compare tw bitmap
HBITMAP hbmp1 = (HBITMAP) SignatureBitmap;
HBITMAP hbmp2 = (HBITMAP) bitmap;
BITMAP bmp1, bmp2;
GetObject(hbmp1, sizeof(BITMAP), &bmp1);
GetObject(hbmp2, sizeof(BITMAP), &bmp2);
if(bmp1.bmBitsPixel != bmp2.bmBitsPixel || bmp1.bmHeight != bmp2.bmHeight || bmp1.bmWidth != bmp2.bmWidth)
AfxMessageBox("prob");
else
{
LPBYTE data1 = (LPBYTE)bmp1.bmBits,
data2 = (LPBYTE)bmp2.bmBits;
DWORD bmWidth = bmp1.bmWidth * (bmp1.bmBitsPixel / 8);
DWORD bmWidthBytes = bmWidth + (2 - bmWidth % 2) * bool(bmWidth % 2);
DWORD bytesize = bmp1.bmHeight * bmWidthBytes;
if(memcmp(data1, data2, bytesize) == 0)
AfxMessageBox("goooooood");
bitmap.Detach();
}
P.S : Two Bitmaps are two snapshot with few second interval (they have same confoguration).
i'm work with VC7, Windows XP with color definition 32bits.
|
|
|
|
|
The problem is as I expected in the previous reply. You are working with DDBs (Decive Dependent Bitmaps) and not DIB (Decive Independent Bitmaps). As far as I know there is no easy way (if exist) to get the bits of DDBs, and the BITMAP structure returned from them points to NULL memory address.
To be more clear any bitmaps got from windows DC , clients DC or any bitmaps created compatible with them are DDBs, and I think, but not sure, that they have variable size.
DIBs are the bitmaps that are normally used in file saving and it has a definit size.
More information about DDBs and DIBs
Hope you are not disappointed, but there is an easy solution, especially since you use VC++7 and have the CImage class.
All you have to do is, instead of bliting into a memory DC compatible with the window DC, you should create a CImage object and blit int it the window DC;
this is how to be get a DIB from DDB using CImage.
CDC *dcP;
CDC memDC;
CRect WndRect;
dcP = GetWindowDC();
GetWindowRect(WndRect);
CImage im;
im.Create(WndRect.Width(), WndRect.Height(), 24);
memDC.Attach(im.GetDC());
memDC.BitBlt(0, 0, WndRect.right,WndRect.bottom, dcP,2 , 2, SRCCOPY);
memDC.Detach();
im.ReleaseDC();
HBITMAP hbmp = im.Detach();
The CImage is included in <atlimage.h> and please note that it needs the GDI+ runtimes. The GDI+ is inlcude in a file named gdiplus.dll, it comes already with WinXP and VS.Net, but if you are going to use it at any system other than WinXP then the DLL should be put with the application file.
For the clipboard part, copying DIBs to clipboard is more complicated than copying DDBs, you may refer to this page in the msdn, SetClipboardData Function .
However if think that you can just copy DDBs to clipboard then convert them to DIB when pasting.
I hope you are not bored from that lecture;)
|
|
|
|
|
MAAK wrote:
Hope you are not disappointed
arf... a litlle bit
MAAK wrote:
HBITMAP hbmp = im.Detach(); //you now have handle to DIB ready for use
ok now i can work with hbmp and it will work fine?
i try to compare the same bitmap :
BITMAP bmp1, bmp2;
GetObject(hbmp, sizeof(hbmp), &bmp1);
GetObject(hbmp, sizeof(hbmp), &bmp2);
if(memcmp(&bmp1, &bmp2, sizeof(bmp1) - sizeof(bmp1.bmBits)))
{
AfxMessageBox("Prob");
}
else
{
LPBYTE data1 = (LPBYTE)bmp1.bmBits, data2 = (LPBYTE)bmp2.bmBits;
DWORD bmWidth = bmp1.bmWidth * (bmp1.bmBitsPixel / 8);
DWORD bmWidthBytes = bmWidth + (2 - bmWidth % 2) * bool(bmWidth % 2);
DWORD bytesize = bmp1.bmHeight * bmWidthBytes;
if(memcmp(data1, data2, bytesize) == 0)
AfxMessageBox("gooooooooooooooood");
}
but i have the same error
there is something which I did not understand?
|
|
|
|
|
You wrote in the last reply the code for obtaining one of the bitmaps, but you did not wrote how the other is obtained (and did not say if it was the same way or not).
Any way put this diagnositc lines of code before the if(memcmp(...
if(data1 == 0)
AfxMessageBox("Error in bitmap 1");
if(data2 == 0)
AfxMessageBox("Error in bitmap 2");
if the data of an HBITMAP is NULL then it should be either a DDB or and invalid handle, however if it's invalid handle the BITMAP structure won't be obtain in the first place. So, if the BITMAP structure is obtained successfully and the data is NULL then it's probably a DDB. If you debugged the program and stepped after the two calls to GetObject() you may check the values of the bmp1 and bmp2 , if the HBITMAP is for a DDB you'll see all the members have normal values except the bmBits, which will contain 0.
By the way, do not compare the BITMAP structure using memcmp() because if both are inavalid you may obtain unexpected reults
|
|
|
|
|
hi,
in degug i see data1 & data2 are not good :
data1 = 0xcccccccc <Ptr> incorrect
data2 = 0xcccccccc <Ptr> incorrect
now i try to convert DDB to DIB....
but it is very confused for me.
|
|
|
|
|
You know how get pointer on the bitmap which is in clipboard ??
THX
|
|
|
|
|
very confused: u want to compare a lots bitmaps, but last request sounds that there are lots of bitmaps on clipboard.
the key for fast comparing is if u can get bitmap buffer properly (BITMAP structure does not work always), where are those bitmaps? in files? VC resource?
includeh10
|
|
|
|
|
Hi,
I have an MFC app with ActiveX controls as child views.
The frame's accelerator handling seems to catch hotkeys and translate them into menu commands (e.g. Ctrl-C --> ID_EDIT_COPY), even though the ActiveX has the focus.
One of the controls needs a fairly extensive keyboard handling, that might in certain cases even interfere with the "application" hotkeys.
Now I see three solutions, and am looking for recommendations which route to take:
a) adding all accelerators to the MFC application, and handling the WM_COMMAND's. Doesn't sound like a good design though (as the ActiveX'es should be allowed to define their own hotkeys)
b) "somehow" separate the accelerator tables - the nicest would be one for the applicaiton, and one provided by the ActiveX - is this possible?
c) Usign a keyboard hook as long as one of activeX has focus.
d) Other ideas?
TIA
Peter
So many people long for eternity that don't know what to do on a rainy sunday afternoon. [sighist] | [Agile Programming] [doxygen] If you look for evil in me you will find it whether it's there or not.
|
|
|
|
|
hi,
i want to send a message from a thread to my Dialog, but how do i get the HWND value from my dialog? I created the dialog by doing DoModal()
thanks in advance,
[]D [] []D []
|
|
|
|
|
does GetSafeHwnd() not work?
Bryce
|
|
|
|
|
nope, it gives back a NULL value... so i need to get it in another way...
i don't even know if the dialog has its own HWND, maybe i need to get it in a different way.
[]D [] []D []
|
|
|
|
|
lets see...fromthe help files
CWnd::GetSafeHwnd
HWND GetSafeHwnd( ) const;
Return Value
Returns the window handle for a window. Returns NULL if the CWnd is not attached to a window or if it is used with a NULL CWnd pointer.
are you getting the hwnd before you start the thread?
Bryce
|
|
|
|
|
Sorry, i got the solution(STUPID STUPID!!!), i wanted to get the HWND value BEFORE i did a DoModal() on my dialog,
no wonder it didn't work! Now i set the HWND value of the thread at the OnInitDialog with GetSafeHwnd() and it works fine! ;)
thanks for your help!
[]D [] []D []
|
|
|
|
|
hi, how does one hide the title bar in an SDI app?
cheers
Bryce
|
|
|
|
|
ModifyStyle(WS_CAPTION, 0);
SetWindowPos(NULL, 0, 0, 0, 0, SWP_DRAWFRAME |
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
rechi
|
|
|
|
|
Hi all,
I need a little help here . I have a simple program using Common control stuffs that require commctlr.h and comctl32.lib.
I created the project using Visual Studio .Net default template for Win32 Console application that includes stdafx.h precompiled header. Somehow this precompiled header makes the compiler not recognize the INITCOMMONCONTROLSEX structure defined in commctlr.h even though I've set up the project appropriately (correct path etc.)
I noticed in the commctlr.h the INITCOMMONCONTROLSEX is surrounded by conditional (_WIN32_IE >= 0x0300). I thought that my project re-defined _WIN32_IE to be less that 0x0300 somewhere, but after I did intensive search, it's nowhere to be found.
Anyway, does anybody know what's happening here? Could you help me please?
NOTE: If I start the project from the scratch (i.e. without using the precompiled header), it compiles fine and smooth.
Thanks alot,
d-man
|
|
|
|
|
|
|
Hi,
I need to implement uint40, where the compiler I am using (in an embedded environment) only supports up to uint32. It would be interesting to have a look at C++ implementations (or even C) for int40 or int64. The only one I found was the Putty C implementation of int64.
Regards,
Victor
phpWebNotes is a page annotation system modelled after php.net.
http://webnotes.sourceforge.net/demo.php[^]
|
|
|
|
|
__int64 is a built-in type in VC++.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Am not sure if this might help, but it need a good Assembly programmer(I barely know it myself).
This is how VC++ implement the __int64 using Assembly, remember that all processors register are 32 (except 64 bit CPU of course) and all operations are done on them at the processor level.
Anyway these are C++ statements with corresponding Assembly, it you may be able to implement using Assembly.
__int64 l1, l2, l3;
l1 = 256;
00417053 mov dword ptr [l1],100h
0041705A mov dword ptr [ebp-14h],0
l2 = 128;
00417061 mov dword ptr [l2],80h
00417068 mov dword ptr [ebp-24h],0
l3 = l1 + l2;
0041706F mov eax,dword ptr [l1]
00417072 add eax,dword ptr [l2]
00417075 mov ecx,dword ptr [ebp-14h]
00417078 adc ecx,dword ptr [ebp-24h]
0041707B mov dword ptr [l3],eax
0041707E mov dword ptr [ebp-34h],ecx
l3 = l1 - l2;
00417081 mov eax,dword ptr [l1]
00417084 sub eax,dword ptr [l2]
00417087 mov ecx,dword ptr [ebp-14h]
0041708A sbb ecx,dword ptr [ebp-24h]
0041708D mov dword ptr [l3],eax
00417090 mov dword ptr [ebp-34h],ecx
l3 = l1 * l2;
00417093 mov eax,dword ptr [ebp-24h]
00417096 push eax
00417097 mov ecx,dword ptr [l2]
0041709A push ecx
0041709B mov edx,dword ptr [ebp-14h]
0041709E push edx
0041709F mov eax,dword ptr [l1]
004170A2 push eax
004170A3 call @ILT+1330(__allmul) (411537h)
004170A8 mov dword ptr [l3],eax
004170AB mov dword ptr [ebp-34h],edx
l3 = l1 / l2;
004170AE mov eax,dword ptr [ebp-24h]
004170B1 push eax
004170B2 mov ecx,dword ptr [l2]
004170B5 push ecx
004170B6 mov edx,dword ptr [ebp-14h]
004170B9 push edx
004170BA mov eax,dword ptr [l1]
004170BD push eax
004170BE call @ILT+5340(__aulldiv) (4124E1h)
004170C3 mov dword ptr [l3],eax
004170C6 mov dword ptr [ebp-34h],edx
l3 = l1 % l2;
004170C9 mov eax,dword ptr [ebp-24h]
004170CC push eax
004170CD mov ecx,dword ptr [l2]
004170D0 push ecx
004170D1 mov edx,dword ptr [ebp-14h]
004170D4 push edx
004170D5 mov eax,dword ptr [l1]
004170D8 push eax
004170D9 call @ILT+5345(__aullrem) (4124E6h)
004170DE mov dword ptr [l3],eax
004170E1 mov dword ptr [ebp-34h],edx
there are some function for multiplication and division, but I could not get their code.
|
|
|
|
|