|
The API functions ::PostMessage and ::SendMessage are thread safe!
That means you can use the windows handle (ie the CWnd::m_hWn d) to interact with your MFC classes.
#define MYMESS_CALL_SOME_METHOD (WM_APP + 1)
struct ThreadParam
{
HWND mDlg;
};
UINT MyThreadProc( LPVOID pParam )
{
ThreadParam* p = static_cast<ThreadParam*> (pParam);
::SendMessage(p->mDlg, MYMESS_CALL_SOME_METHOD, 0, 0);
delete p;
}
void CMyDialog::OnSomeButton()
{
ThreadParam* param = new ThreadParam;
param->mDlg = m_hWnd;
AfxBeginThread(MyThreadProc, param);
param = 0;
}
Declare a method in the dialog message map (in the .h file)
...
afx_msg LRESULT OnCallSomeMethod(WPARAM, LPARAM);
DECLARE_MESSAGE_MAP()
Map the message to the method and implement the method (in the .cpp file):
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
...
ON_MESSAGE(MYMESS_CALL_SOME_METHOD, OnCallSomeMethod)
END_MESSAGE_MAP()
LRESULT CMyDialog::OnCallSomeMethod(WPARAM wp, LPARAM lp)
{
callSomeMethod();
return 0;
}
|
|
|
|
|
Michael Jansson wrote: ::SendMessage are thread safe!
Hi Michael,
Could you explain why SendMessage is thread-safe?
Best Wishes,
-David Delaune
|
|
|
|
|
SendMessage is thread-safe because can be called from multiple threads
without unwanted interaction between the threads.
MFC is not thread safe. Use the windows handle CWnd::m_hWnd to interact with MFC classes
and SendMessage and PostMessage to dispatch messages.
|
|
|
|
|
Michael Jansson wrote: SendMessage is thread-safe because can be called from multiple threads
without unwanted interaction between the threads
You mean such as deadlocking due to a blocking call?
Michael Jansson wrote: MFC is not thread safe.
SendMessage[^] is not thread-safe. The function will generally not return until the called function has returned a LRESULT. If the function being called hangs... SendMessage will never return. Using SendMessage between threads is a recipe for disaster.
Best Wishes,
-David Delaune
|
|
|
|
|
|
Thanks the article helped me alot
|
|
|
|
|
I recently started using a Logitech keyboard with several specific special keys - volume control, WWW, E-Mail, Mute, and so on, and they all work. So I'm wondering what it sends when I press them.
The keyboard did not require any special software - just plug it in and go. So I reason that the only thing it can send are keyboard keystrokes, since its a keyboard without host software.
I reason further that if I knew what it sends then I should be able to send the same thing by striking keys on the keyboard. In other words, regardless of what application is running, I should be able to send a sequence of keystrokes that will open up my e-mail client. Am I right?
Does anyone have an idea what's going on here?
Thanks folks..
glyfyx
|
|
|
|
|
I'm pretty sure there are key codes reserved for those special functions.
For instance, the code 198 (just an example) might tell Windows to open the default mail client.
Another tells it to open the default browser.
So it doesn't send key combinations, just certain key codes.
|
|
|
|
|
glyfyx wrote: Does anyone have an idea what's going on here?
I do. You want to read this[^]. It's quite old, but the info is still current. Note that this only documents the standard keyboard device driver, used if you don't install any logitech drivers.
If you install the logitech drivers, the Logitech driver enables a lot more scan codes, and unfortunately, I have the impression that it also switches a number of these standard scan codes.
|
|
|
|
|
Thanks - especially for the link that explains the mystery.
Glyfyx
|
|
|
|
|
Im in the CMainFrame class. I have a CFormView with many screens. In
CMainFrame, how can I get a pointer to my class so that I can access
variables in the CFormView. I have:
<br />
CListCtrl* CMainFrame::GetListCtrl1098()<br />
{<br />
CMyFormView *pView = NULL;<br />
<br />
CListCtrl* pmyListCtrl = &pView->m_list_1098;<br />
<br />
return pmyListCtrl;<br />
}<br />
But *pView is null and I get an error. How can I make
*pView attain access to its class and hence variables?
Please, any response any one can give me will be greatly appreciated.
Sincerely,
Danielle Brina (an overworked graduate student)
|
|
|
|
|
You could try pView = GetActiveView();
You may be right
I may be crazy
-- Billy Joel --
Within you lies the power for good - Use it!
|
|
|
|
|
The problem is, GetActiveView() returns something other than the
CMyFormView which has the listctrl that I want to attain.
Even if I try:
<br />
void CMainFrame::GetListCtrl()<br />
{<br />
CMyFormView *pView;<br />
<br />
CListCtrl* pmyListCtrl = NULL;<br />
<br />
if (pView)<br />
{<br />
AfxMessageBox("view active");<br />
<br />
pmyListCtrl = pView->m_list_ctrl;<br />
<br />
int total = pmyListCtrl->GetItemCount();<br />
<br />
CString s;<br />
s.Format("total = %i", total);<br />
AfxMessageBox(s);<br />
}<br />
}<br />
it doesnt work.
Please any response any one can give me will be greatly appreciated.
Sincerely,
Danielle Brina (an overworked graduate student)
|
|
|
|
|
See my other reply; once again you are trying to use pView without initialising it to point to anything. I would suggest some further study in classes and objects.
It's time for a new signature.
|
|
|
|
|
Your code:
CMyFormView *pView = NULL;
CListCtrl* pmyListCtrl = &pView->m_list_1098;
will not work. You have set pView to NULL and then tried to use it as a pointer to a list control object. You may need to review the relationship between your classes.
It's time for a new signature.
|
|
|
|
|
Dear experts,
I want to design a graphical editor using Irrlicht engine!
my software is divided in to two parts. one user interface and second is a window which Irrlicht uses to draw
on it!
i want to use separate threads to avoid from interfering of GUI in Irrlicht drawing loop! now i need to know which kind of thread i should use for each one!(Worker and UI Threads)
i have used MFC platform!
void Irrlicht_Main_Process()
{
while(true)
{
Draw anythings here
}
return true;
}
Best regards
|
|
|
|
|
Creating a Worker Thread:
A worker thread is commonly used to handle backgrounds tasks
that the you shouldn't have to wait to continue using your application.
Creating a secondary thread is pretty easy task. There are only two steps:
Step 1. Create a function which will be executed by secondary thread.
This function has your code which suppose to executed in secondary thread.
UINT ProcName(LPVOID param)
{
{
Do Something
}
return 0;
}
Step 2. Create thread by calling MFC function AfxBeginThread.
AfxBeginThread( ProcName, param, priority );
This thread remains active as long as thread's function is executing.
When thread function exits, the thread is destroyed.
You can set thread priorities according to your requirement.
Multithreading using MFC
http://www.dotnetheaven.com/Uploadfile/mahesh/MultithreadingUsingMFC05212005025727AM/MultithreadingUsingMFC.aspx
MFC User Interface Threads
http://www.codersource.net/MFC/MFCAdvanced/MFCUserInterfaceThreads.aspx
A multithreaded, OpenGL-enabled application
http://www.codeproject.com/KB/openGL/GLBase.aspx?msg=1865649
...
|
|
|
|
|
Duplicate posting, already in QA.
|
|
|
|
|
Michel Godfroid wrote: Duplicate posting, already in QA.
How many forums are you watching
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You
|
|
|
|
|
All of them, I was bored yesterday. I draw the line at Perl
|
|
|
|
|
WAVEFORMATEX in_wfx;
in_wfx.wFormatTag = WAVE_FORMAT_PCM;
in_wfx.nChannels =1;
in_wfx.nSamplesPerSec =8000;
in_wfx.nAvgBytesPerSec =16000;
in_wfx.nBlockAlign =2;
in_wfx.wBitsPerSample =16;
in_wfx.cbSize = 0;
how to convert above form to following form?
WAVEFORMATEX out_wfx;
out_wfx.wFormatTag = WAVE_FORMAT_PCM;
out_wfx.nChannels =1;
out_wfx.nSamplesPerSec =8000;
out_wfx.nAvgBytesPerSec =8000;
out_wfx.nBlockAlign =1;
out_wfx.wBitsPerSample =8;
out_wfx.cbSize = 0;
|
|
|
|
|
| how to convert above form to following form?
|
| WAVEFORMATEX in_wfx;
| in_wfx.wFormatTag = WAVE_FORMAT_PCM;
| in_wfx.nChannels =1;
| in_wfx.nSamplesPerSec =8000;
| in_wfx.nAvgBytesPerSec =16000;
| in_wfx.nBlockAlign =2;
| in_wfx.wBitsPerSample =16;
| in_wfx.cbSize = 0;
|
|
|
| WAVEFORMATEX out_wfx;
| out_wfx.wFormatTag = WAVE_FORMAT_PCM;
| out_wfx.nChannels =1;
| out_wfx.nSamplesPerSec =8000;
| out_wfx.nAvgBytesPerSec =8000;
| out_wfx.nBlockAlign =1;
| out_wfx.wBitsPerSample =8;
| out_wfx.cbSize = 0;
|
The nAvgBytesPerSec and nBlockAlign should be calculated:
out_wfx.nBlockAlign = out_wfx.nChannels * out_wfx.wBitsPerSample / 8;
out_wfx.AvgBytesPerSec = out_wfx.nBlockAlign * out_wfx.nSamplesPerSec;
out_wfx.nAvgBytesPerSec = out_wfx.nSamplesPerSec * out_wfx.nBlockAlign;
...
|
|
|
|
|
Currently using CreateFile and WriteFile functions.
I'm using
LARGE_INTEGER Position = Download->BytesDownloaded;
SetFilePointerEx(File, Position, NULL, FILE_END);
Keeps returning unable to convert _int64 to LARGE_INTEGER.
I read the structure of LARGE_INTEGER defined in WinNT.h.
Their is a LONGLONG declaration in it, but can't use it.
|
|
|
|
|
Fareed Rizkalla wrote: LARGE_INTEGER Position = Download->BytesDownloaded;
I suspect the error is there (BytesDownloaded) is long long or __int64.
Why pass the position anyway? If you are appending, just move the file pointer to the end of the file: SetFilePointer(File, 0, NULL, FILE_END);
|
|
|
|
|
I was using CFile in my project, although I resented everything MFC.
I rewrote the parts that were responsible to file output with WriteFile.
All of a sudden it stopped working without me changing anything in the code. When I wrote the code it was working now all of sudden it doesn't want to do what it's supposed to do.
HANDLE File;
File = CreateFile(LocalPathPFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS | OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE | FILE_FLAG_WRITE_THROUGH, NULL);
WriteFile(File, Data, (DWORD)BytesReceived, NULL, NULL);
CloseHandle(File);
|
|
|
|