|
first of all, edit your post (don't repost all, use the edit link), and put all your code into <pre></pre> tags, so that we can rean your question more clearly.
use also the < and > buttons for your for loops
|
|
|
|
|
Hi there!
I’m trying to use the CAnimateCtrl in a CDialog based class so that I can use it as a kind of CWaitCursor thing, that will show a “Please wait…” message an plays a AVI.
Now, since I would also like to use the “XP Theme”, I’ve defined a “manifest” as a resource, and as a result the AVI file will not play.
In order to make it work, I tried to use a thread as the one in the MSDN sample (CAnimateCtrl::CAnimateCtrl in MFC Library Reference).
The problem is when the CAnimateCtrl is being destroyed it takes too long (?), and it also makes the application crash. The MSDN says that "... If you create the CAnimateCtrl object on the stack, it is destroyed automatically."
Below you can see the most relevant (I think) parts of the code. Can someone please tell me what am I doing wrong?
Thanks in advance.
CWorkingDlg::CWorkingDlg( LPCSTR szLabel, bool bProgress, int nMaxProgress, bool bShowCancel, UINT nIdAVI, CWnd* pParent)
: CDialog(CWorkingDlg::IDD, pParent)
{
m_bCancelState = false;
m_dwThreadId = 0;
m_hThreadAvi = NULL;
m_hEventAvi = NULL;
m_bCancel = bShowCancel;
m_bProgress = bProgress;
m_nMaxProgress = nMaxProgress;
CString strLabel(szLabel);
if(strLabel.IsEmpty())
strLabel = "A processar. Aguarde por favor...";
m_strLabel = strLabel;
if (nIdAVI==0)
nIdAVI=IDR_XX_AVI_RODAS;
m_nAVI=nIdAVI;
EnableModal(pParent);
if(!Create(CWorkingDlg::IDD, pParent))
AfxThrowUserException();
ShowWindow(SW_SHOW);
DispatchMsg();
}
CWorkingDlg::~CWorkingDlg()
{
if (m_hThreadAvi)
{
::PostThreadMessage(m_dwThreadId, WM_STOPCLIP, 0L, 0L);
::WaitForSingleObject(m_hEventAvi, INFINITE);
m_hThreadAvi=NULL;
}
if (m_hEventAvi)
{
::CloseHandle(m_hEventAvi);
m_hEventAvi=NULL;
}
DisableModal(GetParent());
if (GetSafeHwnd())
DestroyWindow();
}
void CWorkingDlg::DispatchMsg()
{
MSG msg;
DWORD dwi=GetTickCount();
while (::PeekMessage(&msg, NULL, 0L, 0L, PM_NOREMOVE))
{
if (::GetMessage(&msg,NULL,0L,0L))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
return;
if ((GetTickCount()-dwi)>2000) // 2s
return;
}
}
UINT CWorkingDlg::MyClipThreadProc(LPVOID pParam)
{
AviInfo *pInfo=(AviInfo *)pParam;
CWnd* pParentWnd = CWnd::FromHandle(pInfo->hWndParent);
CRect rc(10,10,100,100);
CWnd *pAvi=pParentWnd->GetDlgItem(IDC_XX_AVI);
if (pAvi)
{
pAvi->GetWindowRect(&rc);
pParentWnd->ScreenToClient(&rc);
}
UINT nIdAVI=pInfo->nIdAvi;
HANDLE hEvent=pInfo->hEvento;
delete pInfo;
pInfo=NULL;
// Create the animation control.
try
{
CAnimateCtrl cAnimCtrl;
if (!cAnimCtrl.Create(WS_CHILD|WS_VISIBLE|ACS_CENTER,
rc, pParentWnd, IDC_XX_AVI))
{
::SetEvent(hEvent);
return false;
}
// Open the AVI file.
if (!cAnimCtrl.Open(nIdAVI))
{
::SetEvent(hEvent);
return false;
}
// Pump message from the queue until the stop play message is received.
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) && (msg.message != WM_STOPCLIP))
{
switch (msg.message)
{
// Start playing from the first frame to the last,
// continuously repeating.
case WM_PLAYCLIP:
if (!cAnimCtrl.Play(0, -1, -1))
return false;
break;
}
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
cAnimCtrl.Stop();
cAnimCtrl.Close();
}
catch(...)
{
_com_error e(::GetLastError());
TRACE("\n--> Error: %s", e.ErrorMessage());
}
::SetEvent(hEvent);
return true;
}
BOOL CWorkingDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CenterWindow();
m_hEventAvi=::CreateEvent(NULL,TRUE,FALSE,"Event_AVI");
AviInfo *pInfo=new AviInfo;
pInfo->hWndParent=GetSafeHwnd();
pInfo->nIdAvi=m_nAVI;
pInfo->hEvento=m_hEventAvi;
CWinThread *pThread=AfxBeginThread(MyClipThreadProc, pInfo);
if (pThread)
{
m_hThreadAvi=pThread->m_hThread;
m_dwThreadId=pThread->m_nThreadID;
::PostThreadMessage(m_dwThreadId, WM_PLAYCLIP, 0L, 0L);
}
else
delete pInfo;
return TRUE;
}
ALMC
|
|
|
|
|
Did you use your debugger to see where it crashes exactly ?
Moreover, don't post a large segment of code like that (and also use the pre tag to format it a little bit better so that it's readable).
|
|
|
|
|
Hi,
Sorry about the formating...
The debugger is only showing some assembly, and the call stack is somewhere in the MFC...
Not much help...
ALMC
|
|
|
|
|
almc wrote: Not much help...
So start peeling away little bits of code until you are left with only what's necessary to reproduce the problem.
"Talent without discipline is like an octopus on roller skates. There's plenty of movement, but you never know if it's going to be forward, backwards, or sideways." - H. Jackson Brown, Jr.
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Hello,
For what I can see, if I change the thread so that I can call it as a function, the problem also happens... So it's not a thread thing.
But I don't know hat else can I do...
Any ideas?
Thanks for you time.
ALMC
|
|
|
|
|
Hi,
Can we use a bitmap as a background to a dialog by writing the suitable code in OninitDialog function .
Thanks in advance,
Radhika.
|
|
|
|
|
radhika28 wrote: bitmap as a background to a dialog
See WM_PAINT:
Use BitBlt()/StretchBlt() if you want to set the image as a background on the dialog
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
See
<br />
#include AtlImage.h<br />
CImage m_Image;<br />
<br />
m_Image.Load("c:\\0.bmp");<br />
<br />
void CanswerDlg::OnPaint() <br />
{<br />
CPaintDC dc(this);
m_Image.BitBlt(dc.m_hDC,0,0,640,480,0,0);<br />
}<br />
<br />
|
|
|
|
|
I need to find the Spanish and Italian translation of the text which is displayed on the windows message box buttons: OK, Yes, No and Retry. Can anyone provide them, or point me to somewhere where I'd find them myself? I also need the translation of the the word "Back" (as in back to the previous menu) for French, German, Spanish and Italian - google translator seems to interpret it as back-side!
Joel Holdsworth
|
|
|
|
|
Joel, i think you can ask this in the Lounge... it is general enough to be asked there
moreover, you'll get more answers, as the Lounge counts much more people, coming from different technical forums...
|
|
|
|
|
AFAIK, microsoft has a web page with translation of the common "microsoft" control text. Search the msdn for that, or even this forum, there was a thread about that recently.
~RaGE();
I think words like 'destiny' are a way of trying to find order where none exists. - Christian Graus
|
|
|
|
|
yes, he asked it this morning
|
|
|
|
|
I have an edit box and its variable is m_strEdit.Its a multiline edit box.
I want to shwo two string in two lines in that edit box and i have written like this,
......<br />
UpdateData();<br />
m_strEdit = "one"+"\n"+"two";<br />
UpdateData(false);<br />
......
but its showing it as
one|two
in the edit box.
How to solve this.
KIRAN PINJARLA
|
|
|
|
|
Turn the want return property of the edit box to true.(If you like to)
m_strEdit = "one"+"\r\n"+"two";
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
Hi,
I need to detect whether is left mouse button is down..
Do you want how do it?
I uset ::GetCursorPos() but I need to detect mouse flags too..
Thanks
|
|
|
|
|
|
In the properties pane there are messages which you can override.
If you override WM_LBUTTONDOWN it should generate a routine called OnLButtonDown.
At least this is the way I do it.
Hope this is what you are looking for.
|
|
|
|
|
majco333 wrote: ::GetCursorPos() but I need to detect mouse flags too..
case WM_MOUSEMOVE:
if(wParam & MK_LBUTTON)
{
}
break;
Hope that I understood you correctly
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
I know but I need to detect mouse flags out of child window...
|
|
|
|
|
Can you clarify what exactly do you want to do?
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
I have own CWnd object. I need to detect mouse flags when mouse is out of this CWnd object. For example, I to handle mouse move in this
CWnd object but I want to handle mouse move when mouse is out this object.
I wand correct to handle mouse move in this object. Because in this object
is image and I need to change XOffset and YOffset by mouse move - do not only in CWnd object but out of CWnd object too...
|
|
|
|
|
I have a dialog bar (similar to a dialog box) where I have a number of different objects. Now I have a request to write the patient name in a large font in red. I don't have a clue how to do this.
Usually one uses OnDraw(CDC *pDC) where the pDC allows you to draw what you want. For a dialog bar or a dialog box there is no OnDraw and the system does the work for you.
The only way I can think of is to make a bitmap file, where I draw into the bitmap what I want and then I display the bitmap as a picture. This is awkward especially as the program will generally be run from a CD which has no write possibilities.
There must be a better way, the question is can anyone suggest what it is?
Thanks,
Ilan
|
|
|
|
|
First of all, few aside notes:
- A dialog bar is not quite similar to a dialog box, although both can be based on a dialog template.
That because CDialogBar is not derived from CDialog but from CControlBar.
- OnDraw is a virtual member function of CView which is called from within WM_PAINT message handler (OnPaint). Neither CDialog, nor CDialogBar have OnDraw method.
- If you need a text in a dialog box or a dialog bar is easier to put it in a static or edit control rather than drawing it in WM_PAINT message handler.
Given these said, I would like to suggest to derive from CDialogBar, make some "cosmetics", i.e. adding WM_INITDIALOG message handler (CDialogBar has not OnInitDialog virtual function like CDialog), change the edit's font in that handler, and finally set the edit's text color in WM_CTLCOLOR message handler.
Here is a sample code:
class CMyDialogBar : public CDialogBar
{
public:
CMyDialogBar();
protected:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg LRESULT OnInitDialog (WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
MyDialogBar::CMyDialogBar()
{
}
void CMyDialogBar::DoDataExchange(CDataExchange* pDX)
{
CDialogBar::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CMyDialogBar, CDialogBar)
ON_WM_CTLCOLOR()
ON_MESSAGE(WM_INITDIALOG, OnInitDialog)
END_MESSAGE_MAP()
LRESULT CMyDialogBar::OnInitDialog (WPARAM wParam, LPARAM lParam)
{
if (!HandleInitDialog(wParam, lParam) || !UpdateData(FALSE))
{
TRACE0("Warning: UpdateData failed during dialog init.\n");
return (LRESULT)0;
}
CFont font;
font.CreatePointFont(140, _T("Times New Roman"));
CWnd* pEdit = GetDlgItem(IDC_EDIT_PATIENT);
_ASSERTE(NULL != pEdit);
pEdit->SetFont(&font);
font.Detach();
return (LRESULT)1;
}
HBRUSH CMyDialogBar::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogBar::OnCtlColor(pDC, pWnd, nCtlColor);
if(pWnd->m_hWnd == GetDlgItem(IDC_EDIT_PATIENT)->GetSafeHwnd())
{
pDC->SetTextColor(RGB(255,0,0));
hbr = (HBRUSH)::GetStockObject(WHITE_BRUSH);
}
return hbr;
}
Ovidiu Cucu
Microsoft MVP - Visual C++
|
|
|
|
|
Thank you for your reply which I didn't see until this morning. Usually it sends me mail when someone replies and since I received no mail I didn't know that you had replied.
I came up with another solution, where basically I make a static text box to receive the information and I invalidate it whenever I need to update the information. Unfortunately I can't use the WM_INITDIALOG because the user can change the study.
So, I invalidate the static box when I need a change, then validate inside WM_PAINT (which it nicely gives me as a message). Once it is valid, I write on top of the static box with the color and text size which I need. So far, it seems to be doing the job.
Here is the code:
<br />
void CMyToolbar::SetPatInfo(void)<br />
{<br />
int oldColor, bkgColor, oldMode, fontSize = 160;<br />
int i, j;<br />
CFont hFont, *hOldFont;<br />
CBrush br1;<br />
CWnd *wnd1;<br />
CSize sz1, sz2;<br />
CRect rc1;<br />
CString textOut[4];<br />
CDC *pDC;<br />
CCardiacDoc *pDoc;<br />
CCardiacView *vw = CCardiacView::GetView();<br />
pDoc = vw->GetDocument();<br />
textOut[0] = pDoc->m_patName;<br />
if( textOut[0].IsEmpty()) <br />
return;<br />
textOut[1] = pDoc->m_patID;<br />
textOut[2] = pDoc->m_imageData[0].m_acqDateTime.Format("%d-%b-%Y");<br />
textOut[3] = pDoc->m_styName;<br />
if( vw->m_masterFlg <= CCardiacView::VW_CARDIAC_DISP2)<br />
textOut[3] = "Myocardial Perfusion";<br />
<br />
wnd1 = GetDlgItem(IDC_PATINFO);<br />
pDC = wnd1->GetDC();<br />
bkgColor = pDC->GetBkColor();<br />
sz1 = 0;<br />
for( i=j=0; i< 4; i++) {<br />
sz2 = pDC->GetTextExtent(textOut[i]);<br />
if( sz2.cx > sz1.cx) {<br />
sz1 = sz2;<br />
j = i;
}<br />
}<br />
<br />
oldColor = pDC->SetTextColor( RGB(255,0,0));<br />
oldMode = pDC->SetBkMode( TRANSPARENT);<br />
wnd1->GetClientRect(&rc1);<br />
wnd1->ValidateRect(rc1);<br />
sz1.cx = rc1.right;<br />
sz1.cy = rc1.bottom;<br />
br1.CreateSolidBrush(bkgColor);<br />
pDC->FillRect(rc1, &br1);<br />
while( fontSize > 80) {<br />
hFont.CreatePointFont( fontSize, "Ariel", pDC);<br />
hOldFont = pDC->SelectObject( &hFont);<br />
sz2 = pDC->GetTextExtent(textOut[j]);
if( sz2.cx <= sz1.cx) break;
pDC->SelectObject( hOldFont);<br />
DeleteObject( hFont);<br />
hFont.Detach();<br />
fontSize -= 20;
}<br />
for( i=j=0; i<4; i++) {<br />
if( j+sz2.cy > sz1.cy) break;
pDC->TextOut(0,j,textOut[i]);<br />
j += sz2.cy;<br />
}<br />
pDC->SelectObject( hOldFont);<br />
DeleteObject( hFont);<br />
pDC->SetTextColor( oldColor);<br />
pDC->SetBkMode( oldMode);<br />
ReleaseDC(pDC);<br />
}<br />
<br />
void CMyToolbar::OnPaint()<br />
{<br />
CPaintDC dc(this);
SetPatInfo();<br />
}<br />
<br />
void CMyToolbar::Invalidate(void)<br />
{<br />
CWnd *wnd1;<br />
CRect rc1;<br />
wnd1 = GetDlgItem(IDC_PATINFO);<br />
wnd1->GetClientRect(&rc1);<br />
wnd1->InvalidateRect(rc1,0);<br />
}<br />
|
|
|
|
|