|
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.
|
|
|
|
|
I'm just starting to learn C++, and i met a problem error below when i compound it...pls teach me how to correct these errors. Your kindness will be appreciated....thank you.
#include "matrix.h"
#ifndef _NO_NAMESPACE
using namespace std;
using namespace math;
#define STD std
#else
#define STD
#endif
#ifndef _NO_TEMPLATE
typedef matrix<double> Matrix;
#else
typedef matrix Matrix;
#endif
#ifndef _NO_EXCEPTION
# define TRYBEGIN() try {
# define CATCHERROR() } catch (const STD::exception& e) { \
cerr << "Error: " << e.what() << endl; }
#else
# define TRYBEGIN()
# define CATCHERROR()
#endif
the software tells the error at these location:
line6 : error C2871: 'std' : does not exist or is not a namespace
line7 : error C2871: 'math' : does not exist or is not a namespace
line14 : error C2143: syntax error : missing ';' before '<'
line14 : error C2143: syntax error : missing ';' before '<'
|
|
|
|
|
you need to #include the files that contian those namespaces, otherwise the compiler doesn't know what your "using" statements refer to.
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
I'm sure there are hundreds of tools/addins/libraries for detecting memory leaks. Which one do most of you use? What is the best method for detecting the annoyances? is it possible to find the exact function/line?
I'm using Visual Studio VC6 Enterprise if it makes any difference.
|
|
|
|
|