Hi there!
Even if I mark a file as read-only, people can open the file (as
read-only), edit it and save it with other name. I have to prevent
this! I want that the only thing that others can do is viewing the
file or printing it (The file is a georeferencial map, format gtm).
I did the following:
1) I've encrypted the map file
2) I've written an application that decrypts the map file, mark the
file as read only, and opens the map viewer application with the map
file opened
3) If the user closes the loader, the map viewer application is closed
The problem is not letting the user save the file with other name, or
preventing the map viewer application from writing to disk temporarily
(While the loader app is opened).
If the solution is via programming, I need it to be in Delphi or
pascal.
Thanks for the attention! |
Clarification of Question by
gustavolacerda-ga
on
20 Jun 2003 04:43 PDT
Hi people, I've already solved big part of my problem. I did this by
hiding the map viewer menu bar (through Win32 API) called from Delphi.
However, I just can't hide the toolbar save button. If someone know
how to do that through API please tell me and I will consider it an
answer.
There is a message named TB_DELETEBUTTON, which value is greater then
1024. In the MSDN library I've found the following:
"The system only does marshalling for system messages (those in the
range 0 to WM_USER). To send other messages (those above WM_USER) to
another process, you must do custom marshalling."
What do they mean by "custom marshalling? How can I achieve this?
|
Request for Question Clarification by
mathtalk-ga
on
20 Jun 2003 08:33 PDT
Note also the TB_ENABLEBUTTON message, which with the right parameter
can be sent to a "toolbar" control (via its Windows handle) to
_disable_ a button, rather than deleting it. This is probably a
"cleaner" approach since it will preserve whatever the "typical"
indexing of buttons on the toolbar is.
As a general approach to distributing a document in a viewable,
non-editable format, I would suggest considering Adobe's Acrobat.
While no absolute protection can be made from copying, renaming, and
editing files, using a complex format (like Adobe Acrobat) for which
the tools for file manipulation are fairly limited is a good
precaution.
You seem to have reinvented some of this wheel with your approach. If
you are now interested in learning about custom marshalling in the
context of posting high numbered Windows messages across process
boundaries, it would perhaps be best to post a new question.
Custom marshalling is most often associated with COM/DCOM interfaces,
so you'll find a lot of references to that if you search solely on
"custom marshalling".
You'll presumably also need to use a number of SendMessage
interactions in order to identify the Windows handle of the toolbar.
Probably the case where information has to "come back" will create the
greatest challenges for you custom marshalling code.
regards, mathtalk-ga
|
Clarification of Question by
gustavolacerda-ga
on
20 Jun 2003 11:01 PDT
Hi ALL!
Tanks for all your comments.
Let me clarify the question a bit more.
The mapfile has information about routePoints, tracks, etc. So it is
useless transforming the map to pdf, or simply capture a screen,
because I want the final user to be able to search for a point in the
map, view distances between two points etc, and these features are
only posible in the map viewer application (which is the GPS
TrackMaker).
All the messages preffixed with "TB_" are greater then 1024. I tried
to use this TB_ENABLEBUTTON also, but I haven't seen any effect.
Finally, the map viewer is a executable which I call via ShellExecute.
I'm really desperate for a solution, because the author of the map is
already waiting for a solution for 3 months and calls me every day.
I don't modify the question because any solution to my problem, even
if it doen't use de "custom marshalling" will be accepted.
Thanks for your efforts in helping me.
[]'s
Gustavo
|
Clarification of Question by
gustavolacerda-ga
on
20 Jun 2003 11:53 PDT
The main code for my loader is the following:
procedure TForm1.Button1Click(Sender: TObject);
var hwWindow, hwmenu : hwnd;
decryptedFile : File;
lResult : integer;
begin
AssignFIle(decryptedFile,'temp.gtm');
decryptedFile := DecryptFile(EncryptedFile); //Decrypts the
encrypted file
Execute('TrackMaker.exe temp.gtm'); //Opens the map viewer with the
file just decrypted opened
{Here, I hide the File and the Edit menu from the map viewer}
hwWindow := FIndWindow(nil,PChar('GPS TrackMaker'));
hwmenu := GetMenu(hwWindow);
DeleteMenu(hwMenu,0,MF_BYPOSITION);
DeleteMenu(hwMenu,0,MF_BYPOSITION); }
drawMenuBar(hwWindow);
end;
My problem is that the toolbar of the map viewer has a save button,
which I don't want to be enabled.
|
Request for Question Clarification by
mathtalk-ga
on
20 Jun 2003 12:06 PDT
What version of the GPS TrackMaker software are you using?
thanks, mathtalk-ga
|
Clarification of Question by
gustavolacerda-ga
on
20 Jun 2003 12:24 PDT
I'm using the v11.8 (the last version) free edition.
|
Request for Question Clarification by
mathtalk-ga
on
21 Jun 2003 22:35 PDT
Hi, gustavolacerda-ga:
I believe that the limitation on "system marshalling" for Windows
messages below WM_USER only affects the case in which the data passed
within the message structure contains a pointer. Using Windows
messages above that value for interprocess communication is customary,
supported in part by a Windows API function called
RegisterWindowMessage that _always_ supplies values greater than
WM_USER:
[MSDN: RegisterWindowMessage Function]
http://msdn.microsoft.com/library/en-us/winui/WinUI/WindowsUserInterface/Windowing/MessagesandMessageQueues/MessagesandMessageQueuesReference/MessagesandMessageQueuesFunctions/RegisterWindowMessage.asp
For an illustration of this technique in Delphi, see this article:
[Getting the Message by Robert Vivrette]
http://www.undu.com/Articles/991221b.html
Under 32-bit Windows separate processes have independent address
spaces. So a pointer created in Application A cannot be used directly
by Application B. "Marshalling" is in broad outline the
behind-the-scenes manipulations needed to convert Application A's
pointer into a memory reference usable by Application B.
If you were interested in passing a fair amount of data from one
process to another, then it would be necessary perhaps to delve into
that fascinating subject more deeply. However pointers may not really
be an issue for your situation. Let's look briefly at the information
required for "sending" the TB_ENABLEBUTTON message:
[TB_ENABLEBUTTON Message]
http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/toolbar/messages/tb_enablebutton.asp
lResult = SendMessage( // returns LRESULT in lResult
(HWND) hWndControl, // handle to destination control
(UINT) TB_ENABLEBUTTON, // message ID
(WPARAM) wParam, // = (WPARAM) (int) idButton
(LPARAM) lParam // = (LPARAM) MAKELONG (fEnable, 0)
);
where hWndControl is the Window handle of the Trackmaker toolbar which
contains the Save button, message ID TB_ENABLEBUTTON happens to be
WM_USER + 1, and the two final parameters are both integer values
rather than pointers.
idButton = Command identifier (index) of button to enable/disable
fEnable = Enable flag (TRUE for enable, FALSE for disable)
The programming challenges here seems to be:
(1) Determine the hWndControl value for the application toolbar
(2) Determine the index of the Save button within that toolbar
Most likely the answer to question (2) can be determined once and for
all (or at least until a new version of GPS TrackMaker comes out).
But the answer to question (1) needs to be obtained dynamically,
probably by querying for the children of the application's main Window
handle.
Given your list price offered of $10, I'm wondering where your ideal
answer lies in the spectrum between making helpful suggestions that
you can flesh out for yourself and providing well-tested source code
written to spec.
Also, how quickly do you need or want to have such an answer?
regards, mathtalk-ga
|