|
It still doesn't work.
Actually, can DispatchMessage() work with a message handler defined using macro ON_THREAD_MESSAGE ?
|
|
|
|
|
|
That's because by implementing your own message pump instead of using CWinThread ’s you’re bypassing MFC’s message routing architecture. There are always such dangers when mixing low-level code (Win32 calls) and high-level code (MFC’s CWinThread ) without understanding how they relate to each other.
To do what you’re trying to do within the MFC architecture proceed as follows:
1. Override your CMyThread 's OnIdle member function. It should look like this:
BOOL CMyThread::OnIdle(LONG lCount)
{
DoMyWork();
CWinThread::OnIdle(lCount);
return TRUE;
}
2. Remove your CMyThread::Run override.
Steve
|
|
|
|
|
this doesn't work because things in OnIdle() can not be a loop and the framework doesn't loop that function by itself. I need an infinite loop. I have try these two methods:
Method 1: --> my thread can not handle any message from main thread
BOOL CMyThread::OnIdle(LONG lCount)
{
for(;;)
{
DoMyWork();
}
CWinThread::OnIdle(lCount);
return TRUE;
}
Method 2: --> DoMyWork() only run one time after we send message from Main thread to My thread.
BOOL CMyThread::OnIdle(LONG lCount)
{
DoMyWork();
CWinThread::OnIdle(lCount);
return TRUE;
}
I expect DoMyWork() to be loop to run forever !!! There must be a way, isn't it?
|
|
|
|
|
GameProfessor wrote: this doesn't work because things in OnIdle() can not be a loop
It will work: the loop is within MFC's CWinThread::Run function. There should be ***NO*** loop inside OnIdle ! Try it and see. Remember to remove your Run override.
Steve
|
|
|
|
|
i'm sure it wont run because it's the first thing I've tried. !!!
Here's the code:
LRESULT CMyThread::OnMyMsg(WPARAM wParam, LPARAM lParam)
{
MessageBox(NULL,"super man","MyMSG message",MB_OK); // this never show up!!!
return 0;
}
int CMyThread::Run()
{ for (;;)
{
i++;
if (i>=10000)
{
i = 0;
}
}
return CWinThread::Run();
}
BOOL CMyThread::OnIdle(LONG lCount)
{
// TODO: Add your specialized code here and/or call the base class
return CWinThread::OnIdle(lCount);
}
|
|
|
|
|
I know it will; I've just build a test app from scratch and it does. So just try it ok!
Here's code snippits:
---------------------
// From CMyThead's implementation:
BEGIN_MESSAGE_MAP(CMyThread, CWinThread)
//{{AFX_MSG_MAP(CMyThread)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
ON_THREAD_MESSAGE(WM_USER, OnFromUI) // *******IMPORTANT*******
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyThread message handlers
BOOL CMyThread::OnIdle(LONG lCount)
{
DoMyWork(); // *******IMPORTANT*******
CWinThread::OnIdle(lCount); // *******IMPORTANT*******
return TRUE; // *******IMPORTANT*******
}
void CMyThread::DoMyWork()
{
}
afx_msg LRESULT CMyThread::OnFromUI(WPARAM, LPARAM)
{
return 0;
}
// Creating the thead and a dialog:
BOOL CWillWorkApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CWinThread *pThread = AfxBeginThread(RUNTIME_CLASS(CMyThread));
CWillWorkDlg dlg(pThread);
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
// In the dialog:
CWillWorkDlg::CWillWorkDlg(CWinThread *pThread, CWnd* pParent /*=NULL*/)
: CDialog(CWillWorkDlg::IDD, pParent)
, m_pThread(pThread) // *******IMPORTANT*******
{
//{{AFX_DATA_INIT(CWillWorkDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CWillWorkDlg::OnButton1()
{
m_pThread->PostThreadMessage(WM_USER, 0, 0); // *******IMPORTANT*******
}
===========================
CMyThread::DoMyWork() is called continuously and CMyThread::OnFromUI is called when I press a button from a dialog in the main thread (not CMyThread).
Steve
|
|
|
|
|
The reason your code doesn't work is that you haven't removed your Run override as I instructed. MFC's message pump is in CWinThread::Run but your override (CMyThread::Run ) never calls it because it enters an endless loop and the call to MFC's is after it. Remove your Run function entirely.
Steve
|
|
|
|
|
Can any one plz help me to create a file IN VC++ or C++ that can be given some FILE permissions (READ for normal users).The files cannot be deleted also.
Proud To Be an India
|
|
|
|
|
Do you mean a simple text file written through VC++ / C++ code ?
If this is your requirement then try _chmod, _wchmod .
Regards,
Paresh.
|
|
|
|
|
I have a program running under USER mode - and later i have to create a file in administrator mode - setting the privilages and all...
Hope u got my requirement now..
Proud To Be an Indian
|
|
|
|
|
Try using API SetFileSecurity .
Regards,
Paresh.
|
|
|
|
|
Try also using SetNamedSecurityInfo .
Regards,
Paresh.
|
|
|
|
|
Hi,
Check with SetFileAttribute(...) Api.
It will Help You.
Uday kiran
|
|
|
|
|
I was having the same issue. When the ini file was created by someone in the administrators group, the file was only accessible by others in the administrators group. 'Normal' users were denied permission.
So I changed the fourth parameter in the CreateFile() function call to be:
m_hFile = CreateFile(..., ..., ..., GetSAForEveryone(), ..., 0, 0);
SECURITY_ATTRIBUTES* GetSAForEveryone()
{
static SECURITY_ATTRIBUTES SA;
static SECURITY_DESCRIPTOR SD;
static bool FirstTime(true);
if (FirstTime)
{
SD.Revision = SECURITY_DESCRIPTOR_REVISION;
SD.Sbz1 = 0; // reserved
SD.Control = SE_DACL_PRESENT;
SD.Owner = 0;
SD.Group = 0;
SD.Sacl = 0;
SD.Dacl = 0; // This grants access to everyone
SA.nLength = sizeof(SECURITY_ATTRIBUTES);
SA.bInheritHandle = false;
SA.lpSecurityDescriptor = &SD;
FirstTime = false;
}
return &SA;
}
This works great. The file is created so that everyone on the machine can read/write/delete/copy/move it.
However, the next hurdle you will face is that if a user in the administrators group copies/moves the file to another folder, the file is again not accessible by all users. To get around this issue I found a page (http://support.microsoft.com/kb/310316) that addresses the issue. The bottom line is that I set the registry entry mentioned in that article for each user that creates the file. This may not be an acceptable solution in your case but it works for me.
|
|
|
|
|
skornel . .. MY actual requirement is - i have a file, that is having "R" only permision for users... its some thing like a log file. THe program has to be RUN in USER MODE(Restricted permission). But in betweeen i have to switch to admin mode to make some chnges in that file.
Iam trying to use cacl - a windows command to change file permission
Proud To Be an Indian
|
|
|
|
|
graduation need me programme a project:email processng system ,who could help me ?could you give me some suggestions,please?Language:VC++
|
|
|
|
|
I'm working with DirectShow
and I use
CString strFileName = "c://videos//sample.mpg");
wstrMediaFile = strFileName.AllocSysString();
IGraphBuilder->RenderFile(wstrMediaFile, NULL);
I have copy this file to memory using the following code
BYTE *pBuffer = (BYTE*)malloc(20480000);
CFile file;
int result = file.Open("c:\\videos\\sample.mpg", CFile::modeRead);
unsigned long Filesize = file.GetLength();
file.Read(pBuffer, Filesize);
Question: How can I give a sytem file name to the buffer so I can use it
with the RenderFile function?
Thank You
Hector Maturana
|
|
|
|
|
What are you trying to do?
What does a file name have to do with a video buffer?
RenderFile takes the pathname of the file as a parameter. You can't load the file into memory
and use it.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Well, I have to play two file in secuence and I have not find the way to do do it properly.
My first attempt was to create to Graph. while the first rendering is been Run I Pause the second one. As soon as i received the EC_COMPLETE I stop the first file and run the second one. But this solution did not give me a smooth transition. Becouse there is two windows. So I'm planing to create a video fuffer where I merge both files. The first one is local in the HD and the second one is a URL address. I was recomended to use VRM-9 but I just start to study the mixer filter.
Well the idea naming the buffer was something like a ram disk file. So that why I am trying to use CMemFile but CMemFile can not get a system file name.
Well if I sound kind of lost I think I am
|
|
|
|
|
You probaly need to build your own filter graph instead of using RenderFile so you can control the
VMR. Even if you do this though, you'll have to deal with when to play the two streams. The
streams are buffered (5 seconds by default) before they start playing so you'd need to
preroll somehow to get a smooth transition.
A much easier alternative may be to use DirectShow Editing Services to build a timeline based
on the two streams. Then the render engine is used to preview (play) the combined streams.
The render engine in DES handles all the messy work of building a filter graph, connecting
the VMR, and rendering/playing the sreams at the right time. It also provides effects and
transitions you could use between the two videos to make it fancy (some of these don't work
great in preview mode though unfortunately .
Check it out....it may be what you're looking for and save you alot of work. It's in the
DirectShow SDK, which is part of the Platform SDK: DirectShow Editing Services[^]
-- modified at 13:17 Tuesday 1st May, 2007
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
I just finished running the TimeLine sample and it seams that the
featues are there. So I'll dig in the documentation to learn more about DirectShow Editing Service.
Thank You.
|
|
|
|
|
I'll write this in a general form b/c I don't think code is really necessary. So I have two seperate classes A and B. I'm trying to create an object of type A by providing object B to a type A constructor. (Essentially converting it.) I'm also trying to do this the other way around. (Essentially being able to convert it back using a construcotr.) The problem I'm running into is that each class's constructor seems to need the other class to be completely defined first.
Does this approach even make sense? I understand the problem, but I don't have the experience to get around the problem.
Any suggestions?
Thanks,
Harold
|
|
|
|
|
This problem in common enough. Use a forward reference like this:
class B;
class A
{
public:
A(const B &other);
};
class B
{
public:
B(const A &other);
};
A::A(const B &other)
{
}
B::B(const A &other)
{
}
Steve
|
|
|
|
|
I think I tried this before, but where I went wrong was trying to access members of the class before it was defined. Using your code as an example, in the constructor declaration you have in A I used something like B.variable1 and B.variable2. (Actually I was using a pointer instead of &other but I don't think that matters.) So correct me if I'm wrong, but it seems that you are declaring your constructors w/in the class defintions but defining them outside where it is possible to use the class members?
Thanks for your help on this.
-Harold
|
|
|
|