|
static bool CheckPrinterStretchDibSupport(HWND hwndForMsgBox, HDC hdc)
{
// most printers can support stretchdibits,
// whereas a lot of printers do not support bitblt
// quit if printer doesn't support StretchDIBits
int rasterCaps = GetDeviceCaps(hdc, RASTERCAPS);
int supportsStretchDib = rasterCaps & RC_STRETCHDIB;
if (supportsStretchDib)
return true;
MessageBox(hwndForMsgBox, "This printer doesn't support StretchDIBits function", "Printing problem.", MB_ICONEXCLAMATION | MB_OK);
return false;
}
static void PrintToDevice(DisplayModel *dm, HDC hdc, LPDEVMODE devMode, int nPageRanges, LPPRINTPAGERANGE pr, int printRange = 0) {
................
DOCINFO di = {0};
di.cbSize = sizeof (DOCINFO);
di.lpszDocName = filename;
if (StartDoc(hdc, &di) <= 0)
return;
.................
SetMapMode(hdc, MM_TEXT);
int printAreaWidth = GetDeviceCaps(hdc, HORZRES);
int printAreaHeight = GetDeviceCaps(hdc, VERTRES);
int topMargin = GetDeviceCaps(hdc, PHYSICALOFFSETY);
int leftMargin = GetDeviceCaps(hdc, PHYSICALOFFSETX);
.........
// use pixel sizes for printer with non square pixels
float fLogPixelsx= (float)GetDeviceCaps(hdc, LOGPIXELSX);
float fLogPixelsy= (float)GetDeviceCaps(hdc, LOGPIXELSY);
bool bPrintPortrait=fLogPixelsx*printAreaWidth<flogpixelsy*printareaheight;>
BOOL isSameFile = IsSameFile(dm);
int realWidth = printAreaWidth;
int realHeight = printAreaHeight;
// print all the pages the user requested unless
// bContinue flags there is a problem.
for (int i=0; i < nPageRanges; i++) {
assert(pr->nFromPage <= pr->nToPage);
for (DWORD pageNo = pr->nFromPage; pageNo <= pr->nToPage; pageNo++) {
............
StartPage(hdc);
..............
bmp->stretchDIBits(hdc, leftMargin, topMargin, realWidth, realHeight);
delete bmp;
if (EndPage(hdc) <= 0) {
AbortDoc(hdc);
return;
}
}
pr++;
}
Error:
EndDoc(hdc);
}
|
|
|
|
|
also you can do like this:
PRINTDLGEX pd;
LPPRINTPAGERANGE ppr=NULL;
.......
ZeroMemory(&pd, sizeof(PRINTDLGEX));
pd.lStructSize = sizeof(PRINTDLGEX);
pd.hwndOwner = hwndFrame;
pd.hDevMode = NULL;
pd.hDevNames = NULL;
pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | PD_NOSELECTION;
pd.nCopies = 1;
/* by default print all pages */
pd.nPageRanges =1;
pd.nMaxPageRanges = MAXPAGERANGES;
ppr = (LPPRINTPAGERANGE)malloc(MAXPAGERANGES*sizeof(PRINTPAGERANGE));
pd.lpPageRanges = ppr;
ppr->nFromPage = 1;
ppr->nToPage = dm->pageCount();
pd.nMinPage = 1;
pd.nMaxPage = dm->pageCount();
pd.nStartPage = START_PAGE_GENERAL;
if (PrintDlgEx(&pd) == S_OK) {
if (pd.dwResultAction==PD_RESULT_PRINT) {
if (CheckPrinterStretchDibSupport(hwndFrame, pd.hDC)){
if (pd.Flags & PD_CURRENTPAGE) {
pd.nPageRanges=1;
pd.lpPageRanges->nFromPage=currentPageNo();
pd.lpPageRanges->nToPage =currentPageNo();
} else if (!(pd.Flags & PD_PAGENUMS)) {
pd.nPageRanges=1;
pd.lpPageRanges->nFromPage=1;
pd.lpPageRanges->nToPage =pageCount();
}
PrintToDevice(dm, pd.hDC, (LPDEVMODE)pd.hDevMode, pd.nPageRanges, pd.lpPageRanges);
}
}
}
else {
if (CommDlgExtendedError()) {
/* if PrintDlg was cancelled then
CommDlgExtendedError is zero, otherwise it returns the
error code, which we could look at here if we wanted.
for now just warn the user that printing has stopped
becasue of an error */
MessageBox(win->hwndFrame, "Cannot initialise printer", "Printing problem.", MB_ICONEXCLAMATION | MB_OK);
}
}
free(ppr);
if (pd.hDC != NULL) DeleteDC(pd.hDC);
if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames);
if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode);
}
|
|
|
|
|
You will need to put all GDI calls between StartDoc /EndDoc and StartPage /EndPage APIs.
The Doc indicates a print job and the Page indicates a new page.
So basically you will have one pair of StartDoc /EndDoc and several pairs of StartPage /EndPage (One for each page).
«_Superman_»
|
|
|
|
|
|
I'm trying to compile the SysInternals Native app[^] for XP x64 (and other Windows x64 ), so I can create an app which can run during boot-time (similar to chkdsk), but am not having much luck. As SysInternals have stopped supplying native.xip, you can get it from
http://www.dowers.net:8080/ftp/Programs/InsideWin2000/Sysinternals-Website/NATIVE.ZIP[^]
I've installed the Windows Server 2003 DDK, and have started a Windows Server 2003 Free x64 Build environment (using the shortcut). I've then copied all the Native sources and makefile to ddk\inc, as instructed to do so at the bottom of the linked article. However, when I run build.exe, I get two identical errors:
C:\WINDDK\3790~1.183\inc>build
BUILD: Adding /Y to COPYCMD so xcopy ops won't hang.
BUILD: Using 4 child processes
BUILD: Object root set to: ==> objfre_wnet_AMD64
BUILD: Compile and Link for AMD64
BUILD: Computing Include file dependencies:
BUILD: Examining c:\winddk\3790~1.183\inc directory for files to compile.
c:\winddk\3790~1.183\inc - 1 source files (82 lines)
BUILD: Saving C:\WINDDK\3790~1.183\build.dat...
BUILD: Compiling (NoSync) c:\winddk\3790~1.183\inc directory
1>errors in directory c:\winddk\3790~1.183\inc
1>c:\winddk\3790~1.183\bin\makefile.new(1106) : error U1050: Setting TARGETPATH=
C:\WINDDK\3790~1.183\lib in .\sources is not valid - please use obj.
BUILD: nmake.exe /nologo BUILDMSG=Stop. -i NTTEST= UMTEST= NOLINK=1 NOPASS0=1 PA
SS1_NOLIB=1 AMD64=1 failed - rc = 2
BUILD: Compiling c:\winddk\3790~1.183\inc directory
100>c:\winddk\3790~1.183\bin\makefile.new(1106) : error U1050: Setting TARGETPAT
H= C:\WINDDK\3790~1.183\lib in .\sources is not valid - please use obj.
BUILD: nmake.exe failed - rc = 2
BUILD: Compile errors: not linking c:\winddk\3790~1.183\inc directory
BUILD: Done
0 files compiled - 2 Errors
What exactly does the error mean ?
1>c:\winddk\3790~1.183\bin\makefile.new(1106) : error U1050: Setting TARGETPATH=
C:\WINDDK\3790~1.183\lib in .\sources is not valid - please use obj.
How can I fix it ?
Is there any good information on how to correctly setup a build environment for building native apps for both x86 and x64 ?
|
|
|
|
|
You might have much better luck posting your question on a site that's devoted to driver development. They know all about this kind of stuff.
Try this site:
http://www.osronline.com/[^]
Good luck!
|
|
|
|
|
I think you should install the latest version of the DDK (WDK).
The one you are using is very old and probably does not support x64.
The new version, the last time I looked was something like 6001.18002.
«_Superman_»
|
|
|
|
|
Hi.
I'm new in c/c++... and I'm a little confused...
I made a dll in c/c++ (using some example I saw on-line), and now I want to load it in a new project, but it doesn't work.
I paste the dll file in the project debug folder, and I'm using
HINSTANCE myDll = LoadLibrary((LPCWSTR)"TestingDll.dll");
to access to it, but myDll is always empty...Can anyone tell me what possible I'm doing wrong?
Thanks
|
|
|
|
|
All the various dlls that TestingDll.dll is dependent on wuould not be present.
Check out the dependencies of TestingDll.dll using depends.exe and paste all those dlls also in the same folder.
|
|
|
|
|
Thanks for your atention...
At the beginning I thought that was the problem and decided to do something very basic for testings, but I still can not access to it.
For my testings I made:
//MyDll.cpp
#include "MyDll.h"
namespace Functions{
Person MyFunctions::first() {
struct Person myPerson;
myPerson.name = "asd";
myPerson.age = 123;
return myPerson;
}
}
//MyDll.h
namespace Functions{
struct Person {
char *name;
int age;
};
class MyFunctions {
public:
static __declspec(dllexport) Person first();
};
}
Then the DLL file I paste in the new project folder (only this one, because for my point of view I don't need nothing more, because it is very simple and doesn't use/depend nothing more ), right?
In the new project I made:
#include "stdafx.h"
#include "windows.h"
using namespace System;
int main(array<System::String ^> ^args){
HINSTANCE myDll = LoadLibrary((LPCWSTR)"TestingDll.dll");
if(myDll) {
Console::WriteLine("DLL loaded \n");
}
else {
Console::WriteLine("DLL failed to load \n");
}
return 0;
}
And the result always is -> "DLL failed to load".
It doesn't returns any error, but doesn't do what I want .
I apologize, but due to my inexperience I did not understand the problem that could cause this ( for sure is something that I'm doing wrong, or forget).
Can you help me?
|
|
|
|
|
From LoadLibrary documentation [^].
Return Value
If the function succeeds, the return value is a handle to the module.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
BTW possibly you should put the DLL inside the project folder.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Thanks for your atention...
I already have the DLL inside the new project folder, but it still not work and I couldn't understand what could be the cause of this, because it doesn't return any error...
|
|
|
|
|
As stated by the documentation I linked in my previous post, if the LoadLibrary return HANDLE is NULL then you have to call GetLastError in order to get some understanding of what's happening.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Perhaps your quote on Creation could be applied to the other Lord who has created so many dialects of C with so many obscure confusions in syntax.
Regards
Ron
|
|
|
|
|
Maybe. Anyway, strictly speaking, the obstacles that are hurting the OP are functions of an application programming interface (Win32 API ): he isn't dealing with a C language dialect.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Again, CByteArray members GetData & GetSize (togheter with std::string constructor) do the trick, for instance:
CByteArray arr;
arr.Add(0xff);
arr.Add(0x00);
arr.Add(0x10);
arr.Add(0x41);
std::string str((char*) arr.GetData(), arr.GetSize());
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Are you using Visual Studio 2005 or 2008?
You may notice that the Visual Studio puts your exe in a folder called "debug" at the same level as your project folder.
The "debug" folder that's inside your project folder holds only the obj files, and the exe does not run from there.
You have to make sure that you put the DLL into the same folder where the exe file is created.
Solution Folder<br />
|<br />
|---Project Folder<br />
| |<br />
| |-Debug<br />
|<br />
|---Debug <= Put dll here<br />
|
|
|
|
|
I'm using Visual Studio 2008.
I had been careful to paste the DLL in the folder with the .exe file... But it still doesn't work...
It is the first time I tried to do a DLL, it is possible I forgot something, or maybe I'm doing something wrong...
|
|
|
|
|
Does your DllMain() function return TRUE?
A Dll will only load if its DllMain() function returns TRUE.
|
|
|
|
|
I think my DLL code is correct, because I used the DLL in a c# project and it loaded and worked just fine.
My problem is to load in a c++ project.
I read that if we want to use a DLL without de lib file, we must paste de DLL file in the debug project folder (and I did it, because I want it to work without the code files).
Then I used
HINSTANCE myDll = LoadLibrary((LPCWSTR)"Testing.dll");
if(myDll)
Console::WriteLine("DLL loaded \n");
else
Console::WriteLine("DLL failed to load \n");
it always "DLL failed to load ", it doesn't return any error.
Did I forgot something, or am I doing something wrong? (I'm starting with c++, so possible I'm making some mistake).
Thanks.
|
|
|
|
|
Change your code so that it reads as follows:
HINSTANCE myDll = LoadLibrary((LPCWSTR)"Testing.dll");
DWORD Error = GetLastError();
if (myDll)
Console::Writeline("Dll Loaded");
else
Console::Writeline("Dll Not Loaded");
Put a breakpoint at the line that says "Not Loaded."
When the program breaks, inspect the value of the variable Error.
That will be the Windows error code for what went wrong. Post the Error code here, and maybe we can help you figure it out.
|
|
|
|
|
Hi.
Thanks a lot for your help.
I did what you suggested and I got error 126 (unsigned int).
I made a litle search to understand error 126 and its causes...and I found out that I can't cast char* to LPCWSTR, and the solution is just "Use Multi-Byte Character Set" within the projects properties. And it works just fine.
Best regards,
Carla
|
|
|
|
|
Hi,
How do i convert a const string& to CByteArray ?
I have to convert the string to CByteArray and pass the member functions GetData() and GetSize() to a method as parameters
Is it possible or is there an alternative way of converting string to CByteArray.
An example would be appreciated.
Thanks in advance,
Regards,
Mayur M
|
|
|
|
|
Try (I didn't test it...)
CString str = _T("Hi");
CByteArray arr;
int iSize = (str.GetLength()+1) * sizeof(TCHAR)
const BYTE * pByte = (const BYTE *) (LPCTSTR) str;
for (i = 0; i < iSize; i++)
{
arr.Add(pByte[i]);
}
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Thanks for your reply.
The code snippet works fine. But the snippet is for convertion of CString to CByteArray. But i'm looking for a const string conversion to CByteArray.
Even if i use the CString conversion to CByteArray, is there any inbuilt methods rather than using the for loop.
Regards,
Mayur M
|
|
|
|