|
Hi,
Is there a problem writing to a CSocket from a different thread than the one that created it?
I am sending large files so I use a worker thread to do the writing, but it ASSERTS when it check the handle for the socket.
If I call the code from the same thread it seems OK.
TIA
Tony
|
|
|
|
|
Don't take this as the final word on the subject, but I do remember reading specifically in the MFC docs that MFC objects cannot be shared between threads.
( I know, this is a real bummer. )
The solution is to pass the handle of the underlying socket to the worker thread, and then have the worker thread create a new CSocket, and Attach() the passed handle.
Hope this helps,
Rich
|
|
|
|
|
Hi,
Thanks for the quick reply. You know I think you are right there, I should have realised becasue I have seen similar problems before with MFC objects!
I will try it the way you have suggested tomorrow. Right now I need sleep
Thanks again
Tony
|
|
|
|
|
When you wake up, here is some reading for you straight from the MSDN Library:
Windows Handle Maps
As a general rule, a thread can access only MFC objects that it created. This is because temporary and permanent Windows handle maps are kept in thread local storage to help maintain protection from simultaneous access from multiple threads. For example, a worker thread cannot perform a calculation and then call a document's UpdateAllViews member function to have the windows that contain views on the new data modified. This has no effect at all, because the map from CWnd objects to HWNDs is local to the primary thread. This means that one thread might have a mapping from a Windows handle to a C++ object, but another thread might map that same handle to a different C++ object. Changes made in one thread would not be reflected in the other.
There are several ways around this problem. The first is to pass individual handles (such as an HWND) rather than C++ objects to the worker thread. The worker thread then adds these objects to its temporary map by calling the appropriate FromHandle member function. You could also add the object to the thread's permanent map by calling Attach, but this should be done only if you are guaranteed that the object will exist longer than the thread.
Another method is to create new user-defined messages corresponding to the different tasks your worker threads will be performing and post these messages to the application's main window using ::PostMessage. This method of communication is similar to two different applications conversing except that both threads are executing in the same address space.
For more information about handle maps, see Technical Note 3. For more information about thread local storage, see Thread Local Storage and Using Thread Local Storage in the Platform SDK.
|
|
|
|
|
I am trying to implement print and print-preview into a non-MFC application. After a little effort I have managed to create the print-preview function and a non working print function.
I have created a function which is passed a rect for the dimensions and a hdc, this function then creates and returns a HBITMAP compatible with the hdc and the size stated in the rect. I hope to use this function for both print and print preview.
The print preview is simply a dialog box, the HBITMAP is then drawn into the client area.
I'm having problems now trying to correctly draw this bitmap to the hdc returned by printDlg(). I have read all of the (MFC only) projects here on codeproject, but I am left even more confused. I know that I need to stretch the bitmap but all I am left with is a tiny black square.
This is a portion of the print function:
printRect.bottom = GetDeviceCaps(pd.hDC, HORZRES);
printRect.right = GetDeviceCaps(pd.hDC, VERTRES);
StartDoc(pd.hDC,&di);
StartPage(pd.hDC);
HBITMAP table = create_printable_table(pd.hDC,&tmprect,rec);
SelectObject(buf,table);
StretchBlt(pd.hDC,0,0,printRect.right,printRect.bottom,buf,0,0,tmprect.bottom,tmprect.right,SRCCOPY);
EndPage(pd.hDC);
EndDoc(pd.hDC);
Please help me with this one, I have spend far too long splitting hairs
-- modified at 14:02 Sunday 19th March, 2006
|
|
|
|
|
I had a similar problem with one of my projects. Read up on these functions:
SetMapMode(MM_ISOTROPIC);
SetWindowOrg(m_BmpInfo.bmWidth / 2, m_BmpInfo.bmHeight / 2);
SetViewportOrg(pDC->GetDeviceCaps(HORZRES) / 2, pDC->GetDeviceCaps(VERTRES) / 2);
SetWindowExt(m_BmpInfo.bmWidth, m_BmpInfo.bmHeight);
SetViewportExt(pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
"Let us be thankful for the fools. But for them the rest of us could not succeed." - Mark Twain
"There is no death, only a change of worlds." - Native American Proverb
|
|
|
|
|
Most printer DC's dont support bitblt. You need to use StretchDIBits. Thats why it works in preview (a screen DC) and not in print mode.
If you vote me down, my score will only get lower
|
|
|
|
|
Hope I understood your question
you need to print bitmap
HDC hdcPrint=CreateCompatibleDC(
CreateDC(pPrinter->pDriverName,(LPCTSTR)lpdevmode->dmDeviceName,pPrinter->pPortName,lpdevmode));
...
...
...
//function print
{
DOCINFO di;
memset((void *)&pd, 0,sizeof(PRINTDLG));
pd.lStructSize = sizeof(PRINTDLG);
pd.hwndOwner = this->m_hWnd;
pd.Flags =PD_RETURNDC|PD_ENABLESETUPTEMPLATE;
pd.hInstance = NULL;
pd.nMaxPage=1;
pd.nMinPage=1;
pd.nCopies=1;
pd.hDevMode=lpdevmode;
pd.nFromPage=1;
pd.nToPage=1;
PrintDlg(&pd);
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = "Job";
di.lpszOutput = NULL;
SelectObject(hdcPrint,hBitmap);
StartDoc (pd.hDC, &di);
StartPage (pd.hDC);
BitBlt(pd.hDC,150,300,2100,1575,hdcPrint,0,0,SRCCOPY);
EndPage (pd.hDC);
EndDoc (pd.hDC);
DeleteObject(hBitmap);
}
maybe it is some helpful to you
|
|
|
|
|
Hi,
I am working with tool set template (C++ code for Vis.Stu. 6.0). I will pattern my own code after this template.
The template calls a DLL.
In the past when I have called DLLs from my code I have used the:
LoadLibrary(something.DLL);
But I can't find anywhere in the project's code (all the .cpp. .h .c files) where the DLL is loaded.
When I compile the app everything wokes fine so the DLL is working.
Also, when I do a text search on the project directory, I do indeed find the DLL in the files:
.ilk .plg .dsp .pdb and the .exe
I just can't dinf, within the Visual Studio user interface, where the DLL is declared/called/loaded.
Many thanks,
Robert
|
|
|
|
|
Is it possible that the DLL is statically linked to the application at the compile stage, and not dynamically loaded with a call to LoadLibrary?
Look in the project's Properties dialog box and see if the DLL lib file is listed as a dependency.
|
|
|
|
|
Troposphere,
Many thanks for reply/answer.
Indeed you are correct:
In Project Settings | PreLink Tab:
The something.DLL is copied from a source location into
the Debug dir.
In Project Settings | Link Tab:
the something.LIB file is referenced.
I am a bit unclear on the difference between the
.LIB and the .DLL
Thanks again,
Robert
|
|
|
|
|
Basically, when a DLL is linked at compile-time by using the LIB, this embeds information into the EXE file that Windows uses to automatically load the DLL when the process first begins.
So in effect, Windows is calling "LoadLibrary" for you.
There is an excellent explanation on the difference between compile-time linking and dynamic linking in the MSDN library, if you look under "Dlls".
Hope this helps,
Rich
|
|
|
|
|
Thanks Rich
|
|
|
|
|
:-OI have a class:
class CTest<br />
{<br />
public:<br />
char szData1[5];<br />
char szData2[10];<br />
char szData3[5];<br />
<br />
CTest(CString strValue)<br />
{<br />
Init();<br />
<br />
if (strValue.IsEmpty()) {<br />
return;<br />
}<br />
<br />
int nPos = strValue.Find("\n");<br />
if (nPos != -1) {<br />
memcpy(szData1, strValue.Left(nPos), sizeof(szData1));<br />
strValue.Delete(0, nPos + 1);<br />
} else {<br />
memcpy(szData1, strValue, sizeof(szData1));<br />
return;<br />
}<br />
<br />
nPos = strValue.Find("\n");<br />
if (nPos != -1) {<br />
memcpy(szData2, strValue.Left(nPos), sizeof(szData2));<br />
strValue.Delete(0, nPos + 1);<br />
} else {<br />
memcpy(szData2, strValue, sizeof(szData2));<br />
return;<br />
}<br />
<br />
nPos = strValue.Find("\n");<br />
if (nPos != -1) {<br />
memcpy(szData3, strValue.Left(nPos), sizeof(szData3));<br />
strValue.Delete(0, nPos + 1);<br />
} else {<br />
memcpy(szData3, strValue, sizeof(szData3));<br />
return;<br />
}<br />
}<br />
private:<br />
void Init()<br />
{<br />
memset(szData1, 0, sizeof(szData1));<br />
memset(szData2, 0, sizeof(szData2));<br />
memset(szData3, 0, sizeof(szData3));<br />
}<br />
};
I used in MFC application like this
CTest t("1234567890\nabcdefghi\n123456789\n");
TRACE("%s\n", t.szData1);
I got this "12345asdfjpwerpaspo8€gA" that is not my purpose.
Any one can tell why!
Thanks.
Hongjun Ge
-- modified at 2:00 Monday 20th March, 2006
Thanks for all help! I have found solution about this.
class CTest<br />
{<br />
public:<br />
char szData1[5];<br />
char szData2[10];<br />
char szData3[5];<br />
<br />
CTest(CString strValue)<br />
{<br />
Init();<br />
<br />
if (strValue.IsEmpty()) {<br />
return;<br />
}<br />
<br />
int nPos = strValue.Find("\n");<br />
if (nPos != -1) {<br />
memcpy(szData1, strValue.Left(nPos), sizeof(szData1));<br />
strValue.Delete(0, nPos + 1);<br />
} else {<br />
memcpy(szData1, strValue, sizeof(szData1));<br />
goto Reset;<br />
}<br />
<br />
nPos = strValue.Find("\n");<br />
if (nPos != -1) {<br />
memcpy(szData2, strValue.Left(nPos), sizeof(szData2));<br />
strValue.Delete(0, nPos + 1);<br />
} else {<br />
memcpy(szData2, strValue, sizeof(szData2));<br />
goto Reset;<br />
}<br />
<br />
nPos = strValue.Find("\n");<br />
if (nPos != -1) {<br />
memcpy(szData3, strValue.Left(nPos), sizeof(szData3));<br />
strValue.Delete(0, nPos + 1);<br />
} else {<br />
memcpy(szData3, strValue, sizeof(szData3));<br />
goto Reset;<br />
}<br />
Reset:<br />
szData1[sizeof(szData1) - 1] = '\0';<br />
szData3[sizeof(szData2) - 1] = '\0';<br />
szData3[sizeof(szData3) - 1] = '\0';<br />
<br />
}<br />
private:<br />
void Init()<br />
{<br />
memset(szData1, 0, sizeof(szData1));<br />
memset(szData2, 0, sizeof(szData2));<br />
memset(szData3, 0, sizeof(szData3));<br />
}<br />
};
|
|
|
|
|
memcpy(szData1, strValue.Left(nPos), sizeof(szData1));
What happens when sizeof(szData1) is greater than the length of strValue.Left(nPos) ??
|
|
|
|
|
memcpy(szData1, strValue.Left(nPos), sizeof(szData1));
This statement seems to be a problem. This statement copies bytes from the CString object itself, not from the string contained within the CString object.
Try:
memcpy(szData1, (LPCSTR)strValue.Left(nPos), sizeof(szData1));
|
|
|
|
|
Sorry. This method couldn't get the correct result.;P
Hongjun Ge
|
|
|
|
|
Sorry for so many posts, but I just realized that you're doing this all wrong.
You should not be copying strings around with the memcpy() function unless you really know what you're doing.
To copy strings from place to place, look up the functions:
strncpy()<br />
strlen()<br />
<br />
and related functions.
|
|
|
|
|
I've used memcpy this way for clipboard stuff. As long as the CString is not on the receiving end, the LPCTSTR operator is just fine. If it's on the receiving end you would need to call CString::GetBuffer() and CString::ReleaseBuffer accordingly to get a non-constant string buffer.
Unless I'm missing something obvious right under my nose that is.
|
|
|
|
|
I agree. Perhaps I spoke too soon. But I took the assumption that this was a beginner's question - someone not well versed in CStrings and nulls.
|
|
|
|
|
Your fine. I would have to say that I agree they should probably leave their parsing within the confines of CString also. However, they will need to know how to interface code littered with CString with the Win32 API which can be quite a trick sometimes but Paul DiLascia, Joseph Newcomer, and Michael Dunn have all done superb jobs explaining all that.
The newer versions of CString have a Tokenize method but it treats consecutive delimiters as one which can easily lead to corrupt parsing so I would not recommend it at all.
|
|
|
|
|
your copying up to the size of your szBuffer but your forgetting to add the \0 (null terminator) so when you attempt to printf or output the string your getting everything up to the end of the szBuffer and then some.
|
|
|
|
|
Hongjun Ge wrote: char szData1[5];
char szData2[10];
char szData3[5];
Why are you not using CString for these? You can certainly complete the task without it, but since you are using MFC, you might as well take advantage of what it has to offer.
CTest::CTest( LPCSTR lpszValue )
{
AfxExtractSubString(strData1, lpszValue, 0);
AfxExtractSubString(strData2, lpszValue, 1);
AfxExtractSubString(strData3, lpszValue, 2);
}
"Let us be thankful for the fools. But for them the rest of us could not succeed." - Mark Twain
"There is no death, only a change of worlds." - Native American Proverb
|
|
|
|
|
my program use matrix to get rgb
and then i hope that white transform into black
int main(int argc, char* argv[])
{
FILE *fidr;
FILE *fidg;
FILE *fidb;
fidr = fopen("logr.txt","w");
fidg = fopen("logg.txt","w");
fidb = fopen("logb.txt","w");
GBmp ImgA, ImgB;
int i,j,k;
ImgA.load("a.bmp");
unsigned char *rgb;
rgb = (unsigned char*) malloc( ImgA.w*ImgA.h*3*sizeof(unsigned char) );
rgb = ImgA.rgb;
for(i=ImgA.h-1;i>=0;i--){
for(j=0;j<imga.w;j++){
="" fprintf(fidr,"rgb(%3d,%3d)=",i,j);
for(k=0;k<3;k++){
if (k==0)
{
fprintf(fidr," %4d",*(rgb+i="" *="" imga.w="" 3="" +="" j*3="" k));
="" }
="" }
="" if(j="ImgA.w-1)
" {
="" fprintf(fidr,"\n");
="" for(i="ImgA.h-1;i">=0;i--){
for(j=0;j<imga.w;j++){
="" fprintf(fidg,"rgb(%3d,%3d)=",i,j);
for(k=0;k<3;k++){
if (k==1)
{
fprintf(fidg," %3d="" ",*(rgb+i="" *="" imga.w="" 3="" +="" j*3="" k));
="" }
="" }
="" if(j="ImgA.w-1)
" {
="" fprintf(fidg,"\n");
="" for(i="ImgA.h-1;i">=0;i--){
for(j=0;j
|
|
|
|
|
If you don't say what does not work, no-one is going to give suggestions.
When you post code, please use the "pre" tag (below the signature box) so the indenting is not lost.
|
|
|
|
|