|
Hi All
I have a problem to get GetClipboard data?I have a code which is working fine for copy data.I read all data which is copy from system.But problem is when i use Cut option then i am geting NULL Data.Plz help me
LPDATAOBJECT pDO;
TCHAR szPath12[MAX_PATH];
HRESULT hr = OleGetClipboard(&pDO);
FORMATETC fmt = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM stgm;
hr = pDO->GetData(&fmt, &stgm);
if(S_OK == hr)
{
UINT nFiles = DragQueryFile((HDROP)stgm.hGlobal, -1, NULL, 0);
int i = 0;
for( i = 0; i < nFiles; i++)
{
ij=1;
DragQueryFile((HDROP)stgm.hGlobal, i, szPath12, MAX_PATH);
szPath12;
}
ReleaseStgMedium(&stgm);
}
pDO->Release();
|
|
|
|
|
Hi
I am getting the error show below.This is the linker error and i am not able to resolve it.I am afraid that I am giving improper selection in the Properties.
Kindly help me out.
1>AltABFUtil.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
1>msvcprt.lib(MSVCP80.dll) : error LNK2005: "class std::basic_string<char,struct>,class std::allocator<char> > __cdecl std::operator+<char,struct>,class std::allocator<char> >(class std::basic_string<char,struct>,class std::allocator<char> > const &,class std::basic_string<char,struct>,class std::allocator<char> > const &)" (??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@0@Z) already defined in abflib.obj
1>msvcprt.lib(MSVCP80.dll) : error LNK2005: "class std::basic_string<char,struct>,class std::allocator<char> > __cdecl std::operator+<char,struct>,class std::allocator<char> >(class std::basic_string<char,struct>,class std::allocator<char> > const &,char const *)" (??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@PBD@Z) already defined in abflib.obj
1>LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library
|
|
|
|
|
You are trying to link with two different versions of the C runtime library (MSVCRT). This usually occurs because you are linking with object code or a static library that was compiled against a different variant of the CRT.
Make sure that all of your code uses the same run-time library option (it's in the C/C++ compiler properties, in the Code Generation page).
|
|
|
|
|
It seems that you are using STL. The possibility is that the variable you are using in the AtlABFUtil.cpp is already been defined in abflib.cpp. Have you included abflib.cpp into atlABFUtil.cpp ? Can you post code snippet for more details ?
|
|
|
|
|
When trying to create CMDIChildWnd in a worker thread I get an ASSERT fails in winmdi.cpp:
if (pParentWnd == NULL)
{
CWinThread *pThread = AfxGetThread();
ASSERT(pThread);
CWnd* pMainWnd = pThread->m_pMainWnd;
ASSERT(pMainWnd != NULL);
ASSERT_KINDOF(CMDIFrameWnd, pMainWnd);//****this line fails
pParentWnd = (CMDIFrameWnd*)pMainWnd;
}
S I guess the parent window is not being set correctly. How can this be set?
|
|
|
|
|
You *have* to create the child window in the same thread its parent was created on. My usual rule is to keep *all* windowing operations within one thread. If you need to create a window in response to an event in a worker thread, post a message across from the worker thread to the main UI thread (posting messages is allowed from worker threads to the UI thread).
|
|
|
|
|
which connectivity(ado, rdo dao, odbc) method should be used to connect mfc application with ms access?
Help me plz.
Thanks in advance.
Dare to dream
|
|
|
|
|
Open Database Connectivity [ODBC]
Girish
Software Developer
|
|
|
|
|
|
Is there any sourc framework code that i can use ? just like Syncfusion Essential Studio(SES), but "SES" is .net based, the startup time is too long for my customers, so i need to find a mfc based source library.
CAD method is not prefer for my customers, they like visio method.
thank you for you help
|
|
|
|
|
Hi,
I use .NET almost all the time, and almost all my apps start up in less than 1 second.
If it takes longer, something inside the app is probably wrong.
Also, very complex apps may take longer, whatever the technology; MS Word is not .NET based!
|
|
|
|
|
I do a test of build a winform and a mfc dialog app, which only contain a visio11 activex control. The startup time is very different, .net winform app sometimes costs about 10 second, but mfc dialog only cost 2~3 second. I have no ideal of accelerating the startup time of the .net winform app.
|
|
|
|
|
and the startup time i said refer to the "cold" start, that's to say, after i restart the computer, the first time i run the .net based app
|
|
|
|
|
I am writing any application using C++ and MFC. Please consider the following two class member functions:
<br />
void ReportASuccess()<br />
{<br />
successCount ++;<br />
this->Invalidate();<br />
}<br />
<br />
void ReportAFailure()<br />
{<br />
failCount ++;<br />
this->Invalidate();<br />
}<br />
There two functions will be called many thousands of times by several worker threads to report results. I am concerned that the increment of the counters successCount and failCount is not thread safe. That is, if the thread loses focus in the middle of the increment, there could be a problem. Do I need to worry about this, and if so, what is the way around it?
By the way, the two member functions shown above are part of class that handles the GUI.
Thanks
Bob
|
|
|
|
|
Hi,
if this is a GUI part, i.e. some Control (maybe a Form), then those functions
have to be executed by the main thread aka GUI thread, hence successCount and failCount
are single-threaded variables; the GUI thread cannot preempt itself.
If your worker threads are to call these methods, you need a mechanism to defer the execution
to the GUI thread, something similar to Control.Invoke in .NET
FYI: the general solution for thread-safety involves synchronization of some kind, here
locks could be appropriate; you are aware of the _Interlocked functions, such as _InterlockedIncrement, are you?
|
|
|
|
|
For example, create a mutex using CreateMutex[^] and use WaitForSingleObject[^] to wait for access, something like this:
void ReportASuccess()
{
if (WaitForSingleObject(handle_to_your_mutex, INFINITE) == WAIT_OBJECT_0)
{
successCount ++;
this->Invalidate();
ReleaseMutex(handle_to_your_mutex);
}
}
void ReportAFailure()
{
if (WaitForSingleObject(handle_to_your_mutex, INFINITE) == WAIT_OBJECT_0)
{
failCount ++;
this->Invalidate();
ReleaseMutex(handle_to_your_mutex);
}
}
If your Invalidate() method belongs between WaitFor... and Release depends on what it does. Generally, i think, a thread will not loose control over the CPU in the middle of an increment/decrement operation, however, this might change with a multicore or multiprocessor system.
As an alternate solution, if your ReportASuccess and ReportAFailure methods are used to control the GUI thread, you could use PostMessage[^](or rather PostThreadMessage[^]) to signal events (just try not to flood your GUI thread with messages).
On a sidenote, be careful with updating the GUI from a different thread than it was created in because this might -and probably will- lead to failures and deadlocks.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
Thanks for the response. I am leaning towards using the PostMessage approach. I am wondering why you said PostMessage rather than SendMessage. Is one better than the other?
I am also thinking that if I wanted to use the locking approach, that I should use two locks. That is, when one thread is reporting success, the other thread can report failure. Maybe I did not give you enough information. Each thread represents a simulation of a stochastic process. Some times, due to luck, they will report success. Other times, they will report failure. What user cares about is the percentage of time they report success. Right now, it is taking about 10 milliseconds per simulation and when the program is put into use, the user will be doing about 1 million simulations per run.
With that said, if I use the locking approach, is there any reason to use only one lock?
Thanks
Bob
|
|
|
|
|
If you use SendMessage you are actually calling the message handler directly from the same thread you called SendMessage in, while if you use PostMessage, you are placing the message in the other thread's message queue and it will handle the message when it gets to it in its own thread. So basicly, if you use SendMessage, the message handler will run in the same thread that called SendMessage, if you call PostMessage, the message handler will run in the GUI thread (or at least the thread that owns the message queue).
For the locking aproach, you can use 2 different locks, there was no special reason why i used the same mutex, and using 2 different locks is probably better for performance, i was just lazy...sorry.
It really mostly depends on what resources the two methods access, since you are increasing two different variables you don't need to have the same lock for both, but if they use the same Invalidate method which might access resources which should not be accessed by multiple threads at the same time you would need to use the same lock. Depends on the situation and structure.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
Thanks for the response. I noticed that there are three PostMessage functions. One is in the Windows API, one is a member of the class CWindow and the other is a member of the class CWnd. Since I want the message to be processed by the GUI thread, your advice on PostMessage vers SendMessage is right on target. However, I am not sure which of the three PostMessage functions to call. I am thinking that I should call CWnd::PostMessage(). Does it matter which one I call?
I would also like to say that the codeproject has quickly become one of my favorite websites due to people like Code-o-mat.
Bob
|
|
|
|
|
FYI - It is NOT true that SendMessage() called from a different thread the window was
created on calls the windowproc on the different thread. If it's called from a different
thread, that thread is blocked and the WindowProc is called on the thread the window was created on.
So you can use ::SendMessage() from a different thread than the window was created on, but be
aware the blocking nature is different than the non-blocking nature of ::PostMessage().
Also, if those variables you are incrementing are integers <= the native integer size
for the processor you're running on, then the increment operation is most likely atomic
so it is thread safe. The variables should be marked as volatile, however, or better yet,
use interlocked increment operations as mentioned by Luc.
The Invalidate calls are NOT thread safe if "this" is a CWND (or derived) pointer.
If you end up locking the operations, you may want to use a critical section instead of a mutex.
You only need a mutex if other processes need synchronized access...
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: FYI - It is NOT true that SendMessage() called from a different thread the window was
created on calls the windowproc on the different thread. If it's called from a different
thread, that thread is blocked and the WindowProc is called on the thread the window was created on.
So you can use ::SendMessage() from a different thread than the window was created on, but be
aware the blocking nature is different than the non-blocking nature of ::PostMessage().
I didn't know that, thanks for the information Mark, i'm sorry for the misleading post. Till this point i was completely sure SendMessage would directly call the handler. Guess i'm an idiot, but we have a saying here, "a good priest learns till death".
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
Heh no problem I personally wouldn't be here if I didn't learn
stuff all the time.
This topic gets even trickier when you throw MFC into the mix, where some
operations may be thread safe, some aren't thread safe, and none are guaranteed
to always be thread safe. Your signature tag-line comes into play pretty quickly.
Cheers!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Afaik CWnd::PostMessage doesn't do anything else but calls the API PostMessage specifying the handle of the window it represents, so there's not much difference between those two, however, if we stick to the general rule of not handing CWnd objects (pointers) over to different threads, i'd say, go for the api call. It's also somewhat safer since if your CWnd gets for some reason deleted then if a thread tries to call its CWnd::PostMessage it will give you the dreaded Access Voilation error. However, if you specify an invalid handle to the API PostMessage it will check that handle to see if a window with that handle exists and if not, then it will simply not post any message to it, thus, no crash. I have no idea about CWindow::PostMessage.
Alternatively you could use PostThreadMessage to post thread messages, these work almost the same way as window messages but they are not targeted at specific window procedures (their target hWnd will be NULL). If you use window messages, note, that in certain circumstances they can get lost. For example, when the user starts dragging a window in the GUI thread to move it around, a "custom" message loop starts up which filters out and throws away certain messages (i guess the reason for this is to avoid nasty situations like crashes, but ask Microsoft about that), so it could happen that while the user moves your window, the messages coming from your threads simply disappear in a black hole never to be seen again. However, this does not seem to happen with thread messages.
BobInNJ wrote: I would also like to say that the codeproject has quickly become one of my favorite websites due to people like Code-o-mat.
Thanks, you are making me blush.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
hi,
these days i want to learn CStringArray and CTypedPtrList,so i creat a listbox for this:
private:
CTypedPtrList < CPtrList,CStringArray* > m_ptrListAllListItem;
void CListboxstrDlg::OnBtnAddlistitem()
{
static int sItemIndex = 0;
CString str;
str.Format("[listitem%d]",sItemIndex++);
int nSel = m_list.AddString(str);
CStringArray* pstrArry = new CStringArray [1];
ASSERT(pstrArry != NULL);
TRACE("------the new pstrArry addr is:%x \n",pstrArry);
pstrArry->Add(str);
m_ptrListAllListItem.AddTail((CStringArray*)pstrArry);
m_list.SetCurSel(m_list.GetCount()-1);
}
void CListboxstrDlg::OnBtnDellistitem()
{
int nSel = m_list.GetCurSel();
if (LB_ERR == nSel)
{
return;
}
POSITION pos;
pos = m_ptrListAllListItem.FindIndex(nSel);
if (pos)
{
CStringArray* ptStrArry;
ptStrArry = (CStringArray*)m_ptrListAllListItem.GetAt(pos);
TRACE("the ptStrArry addr is %x \n",ptStrArry);
m_ptrListAllListItem.RemoveAt(pos);
delete ptStrArry;
m_list.DeleteString(nSel);
m_list.SetCurSel(nSel - 1);
}
}
thank u very much!!
modified on Thursday, December 25, 2008 10:07 PM
|
|
|
|
|
okay,i got it!
delete ptStrArry;
->
delete [] ptStrArry;
|
|
|
|
|