|
See the link here[^] that David posted, it should help you.
|
|
|
|
|
Hi friends,
Thanks in advance.
I am using Acrobat Reader Browser document to show PDF file in my application.
But as I drag drop PDF file into internet explorer, it shows page count of PDF file.
How can I get page count in PDF file through C++/VC++.
Thanks,
Subhash Madhukar
|
|
|
|
|
you mean you are opening pdf document in internet explorer (or web browser control) and need to get the page count of opened PDF document?
--Cool_Dev--
|
|
|
|
|
Hi Cool_Dev,
thanks for reply.
I come to know IE use "Acrobat Browser document" ocx control to open pdf file.
I am using same ocx control but it doesn't expose any function to get open PDF page count.
BUT IE do the same.
I also come to know you can get page count by opening PDF in binary format and search for /Count or /Type /Page pattern.
I opened PDF in binary form using CFile and try to read single line and count " /Type /Page " pattern but as it is binary file, I could not able to read single line.
Line end is specified by '\n' or '\r' or '\r\n' i.e. 0x0A or 0x0D 0r 0x0D 0x0A.
To check the regular expression I used CAtlRegExp class.
If i check all these patterns and read single byte at a time, it takes lot of time. So can you please provide me some c++/VC++ code sample if possible to read the single line in PDF or get the page count.
Thanks,
Subhash Madhukar
|
|
|
|
|
I think Adobe Reader(AR) supports OLE Automation, so that another applications can embed AR with in them and automate it programatically. If IE automates AR to open pdf files, there will be two process running in task manager: iexplorer.exe (IE) & AcroRd32.exe (AR). This is not happening when I opened a pdf document in IE. That means IE uses an ActiveX control (Program Files\Common Files\Adobe\Acrobat\ActiveX\AcroPDF.dll) provided by Adobe. You can use this control in your MFC App by inserting "Adobe Reader" activeX control on dialog. You can generate wrapper class for this OCX, but i couldn't find any method to get no. of pages there.
Another way is to automate AR from you application. The Type Library for AR is Program Files\Adobe\Reader 9.0\Reader\AcroRd32.dll. Use OLEView.exe tool of Visual Studio to see the interfaces that AcroRd32.dll provides. There is CAcroPDDoc interface and it has a methods 'Open' to open a pdf document and 'GetNumPages(long*)' to get no. of pages Create wrapper classes for all necessary interfaces using "Add Class from Type Library" in visual studio, instantiate those classes in specified order, invoke methods on them, finally close the document and release the interfaces. Iam sure that this will work for you...
Every problem has n+1 solutions. 'n' is the number of solutions I have tried and '1' is that which is waiting to be tried.
--Cool_Dev--
|
|
|
|
|
Hi Cool_DeV
Thanks for reply,
I am already using first method i.e. to embed ocx control in my application.
I will give a try 2 second method, but i think it may change with diff. version of acrobat reader ?
Thanks,
Subhash
|
|
|
|
|
U r right. There may be changes in type libraries of different versions of acrobat reader. But if u build ur app with a lower version such as 7, that will run even if the installed version is higher one. The reverse my not be possible.
--Cool_Dev--
|
|
|
|
|
Hi guys,
I am almost finished coding a command console for a home project and have just noticed that the static map I used is causing visual studio to whine about leaking memory on program termination. I have included the code for detecting memory leaks
#define _CRTDBG_MAP_ALLOC
#include <cstdlib>
#include <crtdbg.h>
and I have an assert an the end of the program.
assert(_CrtDumpMemoryLeaks() == 0);
The program bombs during the assert. If I remove my static map it terminates without blowing up but keep it it and BAM. I should point out that almost all code has been commented out and almost all source files removed. The static map is not used at all. It is the declaration of the static map in the .cpp file that causes the so called memory leak.
I think it is because the maps constructor is called during start up as it is a static variable and its destructor is therefore called on program termination. However this is after the last line of code so the assert will always trigger .
Is there any way to get visual studio to ignore the static map because I do not think it is an actual memory leak or do I have to have a static pointer to a map instead of a static map and new and delete the stupid thing myself before the assert?
Thx in advance,
Draemstars.
|
|
|
|
|
You shouldn't worry about it.
The map internally allocates memory in its constructor and deallocates in its destructor.
But when you're calling _CrtDumpMemoryLeaks() you destructor has not yet been called.
So you should not have the assert statement at all.
|
|
|
|
|
The assert statement is there to catch other memory leaks. It has already caught leaks when I forgot to call the destroy function for a class and when I used the normal delete operator instead of the array [] delete.
So taking out the assert while developing could mean I leak memory in future due to some other silly thing I do, and seen as no one is perfect I am bound to forget to delete somehthing else sometime and the assert is there to flag any errors I might make.
Therefore I would rather not take it out even though there is currently no memory leak. I was just wondering is there a flag you can set or something you can do to tell visual studio to ignore the static objects during leak testing which would stop the assert triggering every time I close the application.
|
|
|
|
|
You could get the size of the map using std::map::size() , sizeof(std::map::key_type) and sizeof(std::map::value_type) and then assert on memory leaks more than that size.
You could also call std::map::clean() before doing this.
|
|
|
|
|
Checking the size of the leak is a good idea but I have no clue how to get the amount of memory leaked in code. _CrtDumpMemoryLeaks() just throws a wobbler when memory is leaked, it doesn't give any information on how much memory has been leaked, at least not until it shows up in the output window (60 bytes every time).
I assume you mean std::map::clear() (not clean). I already tried it to no avail.
After a lot of reading I think I am just going to go with a static map pointer instead of a static map. That way I can nuke the new'd map memory myself and make sure it is dead and gone before the program ends and memory leaks are checked for.
Thx anyway though.
|
|
|
|
|
Draemstars wrote: Checking the size of the leak is a good idea but I have no clue how to get the amount of memory leaked in code.
Take a look at _CrtMemCheckpoint[^] and _CrtMemDifference[^].
Draemstars wrote: I assume you mean std::map::clear() (not clean).
Yup. Typo.
Draemstars wrote: After a lot of reading I think I am just going to go with a static map pointer instead of a static map.
I wouldn't recommend it. Especially to support some code that is not going to run in the production build.
|
|
|
|
|
Define
_CrtMemState mem_s1, mem_s2, mem_s3; and at some point in your application, after the static map is created, "checkpoint" the memory usage with
_CrtMemCheckpoint(&mem_s1); and near the end, when you want to check for leaks get a 2nd checkpoint and "diff" them
_CrtMemCheckpoint(&mem_s2);
if (_CrtMemDifference(&mem_s3, &mem_s1, &mem_s2))
{
TRACE("....................Detected Memory Leak in Main Loop\n");
_CrtMemDumpAllObjectsSince(&mem_s1);
TRACE("....................End of Memory Dump\n");
} And if you have an iterative process, these two steps work well at the beginning and end of an interation to catch the "incremental" memory leak.
|
|
|
|
|
Cheers, _CrtMemDifference() worked like a charm.
No more incorrect warnings about leaking memory for me.
Thx guys.
|
|
|
|
|
I !
My problem is that : i don't succeed to write on the "Edit" control of a child dialogbox (i wish i want to write on the "Edit" control conteined in the dialogbox "type of character", accessible by the 'notepad.exe' main menu), because (with my code) the clipboard write her content on the 'main window' (and not where i
expect).
The code :
---------------------------------------------------------------------------
#include <condefs.h>;
#include <windows.h>;
#include <stdio.h>;
int main(int argc, char **argv)
{
HANDLE parentWindow, childWindow;
parentWindow=FindWindow(NULL, "Notepad");
if (parentWindow == NULL) { //notepad.exe doesn't running
printf("Notepad is NOT running !\n");
system("PAUSE");
return(0);
}
childWindow=FindWindowEx(parentWindow, NULL, "Edit", NULL);
if (childWindow == NULL) {
printf("I don't know the handle of 'Edit' control !\n");
system("PAUSE");
return(1);
}
SendMessage(childWindow, WM_PASTE, 0, 0); //i write the clipboard in the Edit control
system("PAUSE");
return(0);
}
------------------------------------------------------
I'm too sure that i mess up with the parameters of 'FindWindowEx' function, but where? If you haven't patience or competence to help me, can you suggest me some very good paper (include example in C) about the 'FindWindowEx' function? (or similar functions used to navigate trough 'handle' and external 'window')
I'm using 'Borland C++ 3' IDE, and i'm a very very newbie on C programming under Windows !
Very tnx to all the helper,
Ismaele-junior
|
|
|
|
|
Ismaele.Jr wrote: parentWindow=FindWindow(NULL, "Notepad");
Shouldn't this be:
parentWindow = FindWindow(NULL, "Untitled - Notepad"); In any case, this is not a good idea.
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
Sorry DavidCrow,
i did digit the code BAD.
The true code is like you digit : parentWindow=FindWindow(NULL, "Untitled - Notepad");
But now, how can i do? Can you suggest me some solution or paper?
Very tnx
|
|
|
|
|
Ismaele.Jr wrote: But now, how can i do? Can you suggest me some solution or paper?
Does the clipboard contain data in CF_TEXT format? Does SendMessage() return anything (WM_PASTE doesn't)?
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
Mister,
i think that i did explain bad :
My problem isn't HOW send message to objects with a handle, BUT find the 'exactly handle' of the "Edit" control of dialogbox of notepad.exe with the 'FindWindowEx' function.
It's only my fault : i'm some donkey in english language (unfortunately i'm italian !)
If you have other patience and charity for reply again, very very tnx !
|
|
|
|
|
Try edit in upper case.
childWindow=FindWindowEx(parentWindow, NULL, "EDIT", NULL);
|
|
|
|
|
Tnx but nothing,
the clipboard write again on the "Edit" control of mainwindow...not on the "Edit" control of the child dialogbox.
I'm crazyng ! 
|
|
|
|
|
So you have a dialog box open in notepad and you want to write to an edit box in that dialog?
If so, you need to get the handle to the dialog after you get the handle to notepad and then get the handle to the edit box.
HANDLE notepad = FindWindow(0, _T("Untitled - Notepad"));
HANDLE dialog = FindWindowEx(notepad, 0, 0, _T("Open"));
HANDLE edit = FindWindowEx(dialog, 0, _T("EDIT"), 0);
::SetWindowText(edit, _T("ABRACADABRA"));
|
|
|
|
|
Good morning Superman ! (or Supercoder !!!)
Very, you centred my objective.
Very tnx for the code that yuo posted me, but he doesn't compile with "Borland C++ Builder 3" under Windows XP : why?
I disclose that i admire your knowlege in C/C++ ! It's enviable
The code after your suggestion :
//---------------------------------------------------------------------------
#include <condefs.h>
#include <windows.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
HANDLE notepad = FindWindow(0, _T("Untitled - Notepad"));
HANDLE dialog = FindWindowEx(notepad, 0, 0, _T("Open"));
HANDLE edit = FindWindowEx(dialog, 0, _T("EDIT"), 0);
::SetWindowText(edit, _T("ABRACADABRA"));
return(0);
}
//---------------------------------------------------------------------------
The compiler write me that : [C++Error] provaIndiano.cpp(11): Call to undefined function '_T'.
|
|
|
|
|
_T is a macro to support both UNICODE and NON-UNICODE builds.
Try without that.
int main(int argc, char **argv)
{
HANDLE notepad = FindWindow(0, "Untitled - Notepad");
HANDLE dialog = FindWindowEx(notepad, 0, 0, "Open");
HANDLE edit = FindWindowEx(dialog, 0, "EDIT", 0);
::SetWindowText(edit, "ABRACADABRA");
return 0;
}
|
|
|
|