|
Hi, I tried using Stealing Program's Memory[^][^] in C++. That worked fine for the demo application provided with it, but when I tried to use it with a another application, I was just able to get the total number of Items in the Listview, without the Items details
Could you please help
Thanks
|
|
|
|
|
iceeeeman wrote: Hi, I tried using Stealing Program's Memory[^][^] in C++.
But this link goes to a C# discussion.
iceeeeman wrote: ...without the Items details
Could you please help
Are you using ReadProcessMemory() ? If so, are you checking it's return value (and then using GetLastError() if it fails)?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
Hi David, here's the link: Stealing Program's Memory[^]
Yes, using it.
I difference I noticed is that my source application has a AFX window, but I guess that's not a problem since I m able to get the Item Count !!
|
|
|
|
|
of course integers work fine, they are passed as is, even across process boundaries.
However text/string operations such as GetWindowText and GetItemText need memory to read/write the text data; such memory must reside in the address space of the process where the data lives; you can only access that using those special Windows calls e.g. ReadProcessMemory.
The technique is used (in C#) in my LP#TrayIconBuster[^] article; have a look at the LP_Process class there.
|
|
|
|
|
Already using ReadProcessMemory, here's the code (source: Stealing Program's Memory[^])
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <windows.h>
#include <commctrl.h>
int main(void) {
HWND hwnd=FindWindow(NULL, "Stealing Program's Memory: ListView");
HWND listview=FindWindowEx(hwnd, NULL, "SysListView32", NULL);
int count=(int)SendMessage(listview, LVM_GETITEMCOUNT, 0, 0);
int i;
LVITEM lvi, *_lvi;
char item[512], subitem[512];
char *_item, *_subitem;
unsigned long pid;
HANDLE process;
GetWindowThreadProcessId(listview, &pid);
process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|
PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);
_lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM),
MEM_COMMIT, PAGE_READWRITE);
_item=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
PAGE_READWRITE);
_subitem=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
PAGE_READWRITE);
lvi.cchTextMax=512;
for(i=0; i<count; i++) {
lvi.iSubItem=0;
lvi.pszText=_item;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
lvi.iSubItem=1;
lvi.pszText=_subitem;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
ReadProcessMemory(process, _item, item, 512, NULL);
ReadProcessMemory(process, _subitem, subitem, 512, NULL);
printf("%s - %s\n", item, subitem);
}
VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
VirtualFreeEx(process, _item, 0, MEM_RELEASE);
VirtualFreeEx(process, _subitem, 0, MEM_RELEASE);
return 0;
}
Its working fine for the demo application, I used create a from in VB and used it, it worked there fine too, but not sure what's causing it to show null values for one the application that has AFX window !!
|
|
|
|
|
How do you know that WriteProcessMemory() and ReadProcessMemory() are working?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
could you please let me know the way to chk it out?
Thanks
|
|
|
|
|
read the documentation!
your code is not safe.
(almost) all Win32 functions have a way to report success/failure and/or an error code.
you should use it. ALWAYS.
|
|
|
|
|
In the same way you'd check the return value from any other function.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
Hi just checked it, they seem to return 1
|
|
|
|
|
both of them returned 1, I just noticed LVS_OWNERDRAWFIXED for my source application's list-view, any ideas on the modifications required in the code to get the list of Items
|
|
|
|
|
If you think that style is causing a problem, create another control without it and see what happens.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
|
i load an Cimage file in my SDI MFC (non View/Doc arch.) application & draw some shapes & text on it... tell me how i can save both shapes,texts & CImage in any (jpg,bmp) file format...
|
|
|
|
|
I got the answer to this problem while trying to solve my problem:
CImage image;
HRESULT hr = image.Save(_T("C:\\test.jpg"), Gdiplus::ImageFormatJPEG);
|
|
|
|
|
i'm drawing shapes on it(like circle,rectangle etc) using OnPaint(); .... will it work now??
|
|
|
|
|
No; when you use the CDC in OnPaint, your drawing is going to the screen.
To draw on a bitmap you need to select the bitmap into a device context, then draw on that device context. Like:
CDC *mdc = GetDC ();
HGDIOBJ tmp = mdc->SelectObject(hbm);
image.Attach (hbm);
HRESULT hr = image.Save(_T("C:\\test.tif"), Gdiplus::ImageFormatTIFF);
|
|
|
|
|
i'm not using cdc....i'm using CPaintDC dc...so now wht i have to do??
|
|
|
|
|
CPaintDC is derived from CDC, so you can perform all the same operations on it. It's an object rather than a pointer, so you have to use "." to invoke methods instead of "->".
You can select a bitmap into the CPaintDC:
dc.SelectObject (hbm);
Where hbm is the handle of a bitmap. You can also select a pointer to a CBitmap. (I don't see an overload for CImage).
You then use the drawing methods of CDC. Then (as in my example) you can attach your bitmap to a CImage object, and save it.
There may be a better way of doing this, but this should work.
|
|
|
|
|
what is hbm? plz write full code in detail...
|
|
|
|
|
hbm is a handle to a bitmap. The Windows type is HBITMAP.
|
|
|
|
|
Runtime error: tht hbm is not initialized....?
|
|
|
|
|
|
Hi all,
I've been attempting to draw on an 8bpp grayscale bitmap without success. Here are some of my attempts. Maybe someone can point out what I'm doing wrong.
===================================================
Attempt 1: Create, select, and draw:
In constructor:
CBitmap bm;
bm.CreateBitmap (200, 200, 1, 8, NULL);
In OnDraw:
CDC *mdc=new CDC ();
HGDIOBJ tmp = mdc->SelectObject(bm);
Result: tmp is NULL, indicating failure.
===================================================
Attempt 2: CreateDIBSection
In constructor:
HBITMAP hbm;
BITMAPINFOHEADER bih;
BITMAPINFO bi;
HANDLE hb;
CDC* myDc = new CDC ();
HDC hdc = myDc->GetSafeHdc ();
void* bits;
RGBQUAD rq [256];
initBi ();
hbm = CreateDIBSection (hdc, &bi, DIB_RGB_COLORS, &bits, NULL, 0);
...
void CEightBitDrawingView::initBi()
{
bih.biSize = sizeof (BITMAPINFOHEADER);
bih.biWidth = 200;
bih.biHeight = -200;
bih.biPlanes = 1;
bih.biBitCount = 8;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 14173;
bih.biYPelsPerMeter = 14173;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
memset ((void *) rq, 0, 256 * sizeof (RGBQUAD));
bi.bmiHeader = bih;
bi.bmiColors = rq;
}
Result: This doesn't even compile because the BITMAPINFO bmiColors member is defined as:
RGBQUAD bmiColors[1];
so won't accept more than one RGB color. In fact, nothing I assign to this member compiles! (Could they possibly make it any more complex!?)
Any suggestions would be appreciated! Thanks!
===================================================
|
|
|
|
|
Alan Balkany wrote: CDC *mdc=new CDC ();
HGDIOBJ tmp = mdc->SelectObject(bm);
- do you create the DC anywhere or you just instantiate it? You need to create the DC, a CDC instance alone isn't enough. Where does bm come from? Acording to what you said bm would be a local variable in the constructor, so how would it get to OnDraw?
About the RGBQUAD thing:
Alan Balkany wrote: RGBQUAD bmiColors[1];
this means that an array of RGBQUADs containing a variable number of colors will follow directly the BITMAPINFO structure. I think the biClrUsed member would indicate this in the struct (see the documentation for the structure).
You have to allocate enough memory to contain the bitmap info struct AND the palette after it, you can set the members in the palette -if you like- thorough the bmiColors array. Something like:
BITMAPINFO *bmi = (BITMAPINFO *)malloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255);
...fill the bmiHeader ...
bmi->bmiCOlors[0] = firstColor;
bmi->bmiCOlors[1] = secondColor;
...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|