|
Basically the LButtonDblClk function is using TextOut to put "Hello World" on the screen at the cursors position. The intention is to have the output accumulate on the screen and remain on the screen when resized, minimized or covered by another window etc...
I tried recreating the bitmap each time by changing the conditional statement at the beginning of LButtonDblClk if(!= NULL)delete the bitmap and just have the bitmap created each time the problem with that is the output does not accumulate on the screen.
I will try what you have here to see if my results can improve. Again this code is working, it just paints the background black and I am having trouble figuring out why that is, I have been messing with this same project for a while, maybe I'll try generating a new one and see what happens.
I am puzzled why this is so difficult to solve, although I have not written alot of code I have been doing it for a long time and the programmer has always had to take care of refreshing the screen and keeping the output(text, graphics etc..) on there theirself, at least I have. So what does a novice have to do to get the information or at least a clue to the solution. This cannot be stumping the programming gurus here in this forum, no way.
Thanks again
Terry S.
|
|
|
|
|
So what you intend to do is (correct if I'm wrong):
When user double clicks the left mouse button, draw some graphics and make it permanent.
If I guessed well then you have to:
- Properly erase the background (see [^]).
- Make your painting function (i.e.
ShowIt() ) accepting as argument, a CPaintDC instead of creating its own device context. - Never call directly your paint function (or other drawing code, use instead
InvalidateRect and UpdateWindow to force the painting happen). - inside the button handler just set a flag (a member variable of the class) and use it to conditionally call your painting function inside
OnPaint
For instance:
void Ccom_testView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
m_showit=true;
InvalidateRect(NULL);
UpdateWindow();
}
void Ccom_testView::OnPaint()
{
CPaintDC dc(this);
if (m_showit)
ShowIt(dc);
}
void Ccom_testView::ShowIt(CPaintDC & dc)
{
}
Hope it eventually makes sense.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Actually this makes alot of of sense, I have a better time making sense of things than I do communicating them in a way that makes sense, if that makes sense .
Seriously I think this is going to work for me once I get it implemented properly. I have always been week at passing perameters and therefore I avoid it and never think about the possibilities. I have alot to learn but I'm not going to give up.
Thank you very much for your help, I have learned a great deal just in the communications, that's asside from the code information.
Terry S.
|
|
|
|
|
I thought I had it...
Here is what I got, it all compiles and runs great but I never see anything show up on the window.
What did I do wrong or not do?
void CComViewView::OnDraw(CDC* )
{
CComViewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CPaintDC dc(this);
if(m_show)
ShowIt(dc);
}
void CComViewView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
pos = point;
m_show = true;
m_userIn = true;
InvalidateRect(NULL);
UpdateWindow();
CView::OnLButtonDblClk(nFlags, point);
}
void CComViewView::ShowIt(CPaintDC & dc)
{
if(!m_userIn)return;
maxX = GetSystemMetrics(SM_CXSCREEN);
maxY = GetSystemMetrics(SM_CYSCREEN);
CDC memDC;
CBitmap m_bmp;
memDC.CreateCompatibleDC(&dc);
m_bmp.CreateCompatibleBitmap(&dc, maxX, maxY);
memDC.SelectObject(&m_bmp);
memDC.SetTextColor(RGB(0, 200, 100));
memDC.SetBkColor(RGB(0,0,0));
wsprintf(str, "Hello World");
memDC.TextOutA(pos.x, pos.y, str, strlen(str));
memDC.BitBlt(0, 0, maxX, maxY, &memDC, 0, 0, SRCCOPY);
UpdateWindow();
m_userIn = false;
}
|
|
|
|
|
SimplCodr wrote:
void CComViewView::OnDraw(CDC* /*pDC*/)
{
CComViewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: add draw code for native data here
CPaintDC dc(this);
if(m_show)
ShowIt(dc);
}
You don't need to create a new dc, change to (note I uncommented the pDC argument)
void CComViewView::OnDraw(CDC* pDC)
{
CComViewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
if(m_show)
ShowIt(*pDC);
}
SimplCodr wrote: memDC.BitBlt(0, 0, maxX, maxY, &memDC, 0, 0, SRCCOPY);
This is the mistake, change to
dc.BitBlt(0, 0, maxX, maxY, &memDC, 0, 0, SRCCOPY);
You've to work on the background, there are still some flaws, but it is much better now.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Excellent, I think I have everything I will need I just need to plug away at it for a while before I come crying for more help. Thanks a bunch. 
|
|
|
|
|
You are welcome.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Try [^vc++ in 21 days^] It will give you very good idea of mfc in 2 or 3 days. it's the shortest and most effective way known to me to learn about mfc. it may be a bit dated but the concepts are same and you don't need to spend big bucks to purchase it from nearby second hand bookshop or if you are really smart, you can find an ebook floating around somewhere in this cyberspace. (i know no one likes to spend money on buying fat and boring technical books)
.. and i hope your problem is solved by now.
|
|
|
|
|
I like to learn and books are good way to start... I accually own the predecessor to that book "C++ in 21 days" which I found to be quite good. I also found "MFC From the Ground Up" which is a great book if you are compiling using Visual C++ 6.0, it seems like things are done non-stansard though, you have to change alot things around to get them to compile and run from the VS2005 that I have now. It's really a good thing Microsoft made it difficult to go back to old version of compiler, cause I would have and not learned what I have. Man and I'll tell you from A novices perspective that upgrade has caused me more pain than I ever imagined I could get from writting my simple code. I think there is a new book out something like MFC from the ground up for VS2005, if that's the case I would really like to get a copy of that.
It's people like you and Pallini that make me come here when I need help. You folks are awesome keep up the good work and thank you.
Terry S.
|
|
|
|
|
SAFEARRAY* arr;
int iRes = RestoreFactory(bstrPath, // this function is for c#com object &arr);
// Copy SAFEARRAY* values to output
int iSize;
if ( arr != NULL )
{
iSize = arr->rgsabound[0].cElements;
BYTE *byteArr = new BYTE[iSize];
for (int i = 0; i < iSize; i++)
{
byteArr[i] = ((BYTE)((( char *)(*arr).pvData)[i]));
}
}
The byteArr seems to be wrong!
Is it the right convertion???
Thanks!
|
|
|
|
|
TalSt wrote: The byteArr seems to be wrong!
Namely?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
TalSt wrote:
Convert BYTE* array (unmanaged) to SAFEARRAY
Is it the right convertion???
No.
The code you have posted is converting from SAFEARRAY to BYTE[]. Exactly the opposite of your post title. Can you clarify what it is you are trying to achieve?
Best Wishes,
-David Delaune
|
|
|
|
|
Hello,
Yes. You are right. The title is wrong. It should be: "converting from SAFEARRAY to BYTE[]".
Do you know if the code is correct?
Thanks! 
|
|
|
|
|
Hi TalSt,
Check out this older post [^]where I describe a unique way to build a LPCSTR from a SAFEARRAY. You could use the same technique to convert SAFEARRAY to BYTE.
Best Wishes,
-David Delaune
|
|
|
|
|
Hello everyone !
Here I want to read one of the ListCtrl datas from other process(report style),and write them into my ListCtrl.
Example this code ,I want to read the "Window Task Manager" datas(in Process Tab),and write it into my ListCtrl:
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
......
LONG lStyle = m_ListCtrl.SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE);
lStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES;
m_ListCtrl.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0,(LPARAM)lStyle);
m_ListCtrl.InsertColumn(0,"Name",NULL,100, -1);
m_ListCtrl.InsertColumn(1,"PID",NULL,60,-1);
m_ListCtrl.InsertColumn(2,"User",NULL,120,-1);
m_ListCtrl.InsertColumn(3,"CPU",NULL,60,-1);
return TRUE;
}
void CTestDlg::OnBtnRead()
{
m_ListCtrl.DeleteAllItems();
HWND hWnd,hListview;
hWnd=::FindWindow(NULL,_T("Windows Task Manager"));
hWnd=::FindWindowEx(hWnd,0,"#32770",0);
hListview=::FindWindowEx(hWnd,0,_T("SysListView32"),NULL);
if(!hListview)
{
MessageBox("Listview handle is NULL !");
return;
}
int count = (int)::SendMessage(hListview,LVM_GETITEMCOUNT,0,0);
int i,nItem;
CString strTemp;
strTemp.Format("Total process :%d",count);
MessageBox(strTemp);
CString str1="";
CString str2="";
CString str3="";
CString str4="";
DWORD pid;
HANDLE process;
LVITEM lvi, *_lvi;
char firstitem[512], secitem[512],thirditem[512],fourthitem[512];
char *_firstitem, *_secitem,*_thirditem,*_fourthitem;
memset(firstitem,0,512);
memset(secitem,0,512);
memset(thirditem,0,512);
memset(fourthitem,0,512);
GetWindowThreadProcessId(hListview, &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);
_firstitem=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,PAGE_READWRITE);
_secitem =(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,PAGE_READWRITE);
_thirditem=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,PAGE_READWRITE);
_fourthitem=(char*)VirtualAllocEx(process,NULL, 512, MEM_COMMIT,PAGE_READWRITE);
lvi.cchTextMax=512;
for(i=count; i>=0; i--)
{
lvi.iSubItem=0;
lvi.pszText=_firstitem;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
::SendMessage(hListview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
lvi.iSubItem=1;
lvi.pszText=_secitem;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
::SendMessage(hListview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
lvi.iSubItem=2;
lvi.pszText=_thirditem;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
::SendMessage(hListview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
lvi.iSubItem=3;
lvi.pszText=_fourthitem;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
::SendMessage(hListview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
ReadProcessMemory(process, _firstitem, firstitem, 512, NULL);
ReadProcessMemory(process, _secitem, secitem, 512, NULL);
ReadProcessMemory(process, _thirditem, thirditem, 512, NULL);
ReadProcessMemory(process, _fourthitem, fourthitem, 512, NULL);
str1.Format("%s",firstitem);
str2.Format("%s",secitem);
str3.Format("%s",thirditem);
str4.Format("%s",fourthitem);
nItem = m_ListCtrl.InsertItem(0,str1);
m_ListCtrl.SetItem(nItem,1,1,str2,NULL,0,0,0);
m_ListCtrl.SetItem(nItem,2,1,str3,NULL,0,0,0);
m_ListCtrl.SetItem(nItem,3,1,str4,NULL,0,0,0);
}
VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
VirtualFreeEx(process, _firstitem, 0, MEM_RELEASE);
VirtualFreeEx(process, _secitem, 0, MEM_RELEASE);
VirtualFreeEx(process, _thirditem, 0, MEM_RELEASE);
VirtualFreeEx(process, _fourthitem, 0, MEM_RELEASE);
}
but in some progrmas, when you double click one item,you can edit it as use EditBox. so I can't used the above method to read the data from the control.
How can I read them ?
|
|
|
|
|
wangningyu wrote: Example this code ,I want to read the "Window Task Manager" datas(in Process Tab),and write it into my ListCtrl:
Wouldn't it be easier to just get your own list via CreateToolhelp32Snapshot() and the Process32First() /Process32Next() pair?
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"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
|
|
|
|
|
Sorry , I don't want the list of my processes.
that's only a SysListView32 Style Control of the sample code.
if the edit listcontrol in other programs, how can I read the list ?
modified on Thursday, October 22, 2009 12:42 PM
|
|
|
|
|
Assuming you have the window handle of the control, first send it a LVM_GETITEMCOUNT message. Then for each item, send the control a LVM_GETITEMTEXT message.
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"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
|
|
|
|
|
this item has two windows,you can find the editbox's handle to read text from it.
|
|
|
|
|
do you have happen this problem:
str1's content is equivalent to str2,str3,str4 and str5,how to solve the problem, thank you very much.
|
|
|
|
|
Okay I am trying to lock CD drive (F: here) with the code shown. But DeviceIoControl is returning "error 87: Parameter not correct". Please someone help me. I cannot find out which parameter is incorrcet.
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
void ShowError(void);
int main(){
char szVolume[] = "\\\\.\\F:";
HANDLE hVolume;
DWORD dwBytes = 0;
PREVENT_MEDIA_REMOVAL pmr;
pmr.PreventMediaRemoval = TRUE;
hVolume = CreateFile(szVolume,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(hVolume==INVALID_HANDLE_VALUE){
ShowError();
exit(1);
}
if(DeviceIoControl(hVolume,IOCTL_STORAGE_EJECTION_CONTROL,(LPVOID)&pmr,(DWORD)sizeof(pmr),NULL,0,&dwBytes,NULL)==FALSE){
ShowError();
}
CloseHandle(hVolume);
return 0;
}
|
|
|
|
|
I can't find an error, but maybe you open the device in a wrong way?
MSDN says:
"hDevice [in]
A handle to the device. To obtain a device handle, call the CreateFile function.
Files must be opened with the FILE_READ_ATTRIBUTES access right. For more information, see File Security and Access Rights."
You try to open your device with generic read and write access.
Sorry buts the only thing I found, what could maybe explain this error.
Has hVolume the right value?
(Your check is right, but i wonder what GetLastError() says.)
Edit:
Maybe you should also change your sharing parameter in your CreateFile call (for example try 0 -> no share).
|
|
|
|
|
Yes hVolume is right value. GetLastError returns 0.
GENERIC_READ already has FILE_READ_ATTRIBUTES
Tried using 0 for File sharing but still DeviceIoControl gives error 87 parameter not correct
Thanks for replying, I appreciate it.
|
|
|
|
|
Are you completely sure about F:?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
Yes my DVD drive is F:. and handle returned by CreateFile is valid too.
Thanks for replying
|
|
|
|
|