|
|
Hey guys,
I'm writing a windows interface for a DOS program, which needs to trap the output and send keyboard input to the DOS program. I've tried CreateProcess and rerouting stdin and stdout, but to no avail. I think they've coded the DOS interface using direct BIOS calls or writing to screen memory. Is there any way to trap screen output that has been coded in this way? The other problem is sending keypresses to the program - stdin isn't working either.
Any clues would be greatly appreciated.
Cheers,
Paul
|
|
|
|
|
I have a dll project in visual c++
and I want to have a variable which will change by different exe files which use this dll.
for example if i have
"int i=0; //global var of the dll file
.....
int func
{
if (....)
i++;
}
"
I would like i to be 1 for the next time func is called by a differet exe file.
thanks,
Aviv.
avivhal
|
|
|
|
|
You need to put your data that will be shared across multiple invocations of the DLL into a shared memory segment. For example, the following declares a static variable (connections) in a shared data segment called .SHARDAT
#pragma data_seg(".SHARDAT")
static int connections = 0;
#pragma data_seg()
Cheers,
Tom Archer
Author, Inside C#
Author, Visual C++.NET Bible
A total abstainer is one who abstains from everything but abstention, and especially from inactivity in the af
|
|
|
|
|
and how do I access this variable from various files?
avivhal
|
|
|
|
|
I'm not sure I follow your question.
Here are the steps to share data across multiple invocations of a DLL. In this example, I'm keeping track of the number of connected users to this DLL.
Server side (Dll)
- Create a Win32 DLL (I called mine DllSharedDataServer)
- Create a header file for the DLL (DllSharedDataServer.h)
- Add the following code to define the shared data. Note that I would normally just define this in the DLL's main CPP file, but I'm guessing from your question that your DLL has multiple CPP files, all of which need access to this variable.
#pragma once
#pragma data_seg(".SHARDAT")
static int connections = 0;
#pragma data_seg()
- Add the following function to the DllSharedDataServer.h header file so that clients can query as to the number of connected users.
int GetNumberOfConnections();
- Add an include directive to the DllSharedDataServer.cpp file
#include "DllSharedDataServer.h"
- Update the DllMain function to increment the number of connected users when a client attaches and decrement the counter when a client detaches:
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
connections++;
break;
case DLL_PROCESS_DETACH:
connections--;
break;
default:
break;
}
return TRUE;
}
- Add the GetNumberOfConnections function to return the counter's value
int GetNumberOfConnections()
{
return connections;
}
- Add a DEF file to the DLL and update it as follows so that the GetNumberOfConnections function is exported and the shared data segment is properly defined:
LIBRARY DllSharedDataServer
SECTIONS
.SHARDAT READ WRITE SHARED
EXPORTS
GetNumberOfConnections
- Build the DLL
Client side
- Create an MFC dialog-based app to test with (DllSharedDataClient). In cases like this where the two projects are meant to work together I usually specify the Add to solution option so that it's easier to work on both projects at the same time.
- Include the DllSharedDataServer.h file in the DllSharedDataClientDlg.cpp file.
- In the dialog's OnOK handler place the following call to the GetNumberOfConnections function
void CDllSharedDataClient1Dlg::OnBnClickedOk()
{
int i = GetNumberOfConnections();
CString str;
str.Format("There are currently %ld connections to the DLL", i);
AfxMessageBox(str);
}
- Add the DllSharedDataServer.lib to the DllSharedDataClient project
- Build the client
- Finally, copy the DLL to a folder where it can be found when running the client.
Testing the DLL
Now simply run a few instances of the client and you will see that each time you click the OK button the correct number of connections will be displayed; thereby proving that your data is being shared among multiple connections to the DLL.
Cheers,
Tom Archer
Author, Inside C#
Author, Visual C++.NET Bible
A total abstainer is one who abstains from everything but abstention, and especially from inactivity in the af
|
|
|
|
|
I would like to point out that this method does not guarantee that the variable will be shared. Only if the dll is mapped into the same memory address in each process will it work. If one of the processes remaps the dll because of a collision with another dll then that process will have it's own copy.
Joel Lucsy (jjlucsy@ameritech.net)
|
|
|
|
|
True, but if someone is using something like REBASE to manually remap DLLs for performance considerations, then I figure they already know how to define shared data segments.
Cheers,
Tom Archer
Author - Inside C#, Visual C++.NET Bible
A total abstainer is one who abstains from everything but abstention, and especially from inactivity in the af
|
|
|
|
|
The point, however, is that this problem can manifest itself without a manual REBASE. Say two dlls have not been rebased and are loaded automatically by the system and by themselves would load into the same memory locations. If your dll is loaded second then the shared segment won't be effective.
This problem can be avoided by smartly rebasing your dll itself into a "safe" area, but there are no guarantees. If you know it's always "your" executable that loads it, or that you know what dlls the target executable will load, then you're all set. Global hooks from dlls have a greater chance of remapped since you can't know all the executables that it might be loaded into.
Now, I'm not saying don't use shared memory segments. But I'm just trying to keep everyone informed of the issues.
Joel Lucsy (jjlucsy@ameritech.net)
|
|
|
|
|
Extremely good points, Joel. Thanks for the input!
Cheers,
Tom Archer
Author - Inside C#, Visual C++.NET Bible
A total abstainer is one who abstains from everything but abstention, and especially from inactivity in the af
|
|
|
|
|
Hi All,
I am trying to simulate a ID_FILE_OPEN command from a button click instead of the applications main menu.
Seem like I should just be able to send or post a message, but I have not stumbled on the answer.
A point in the right direction would be appreciated.
Thanks, Paul
|
|
|
|
|
AfxGetMainWnd()->PostMessage(WM_COMMAND,ID_FILE_OPEN,0);
should do the trick
situations to avoid #37: "good morning ... how many sugars do you take in your coffee ... and what was your name again?"
coming soon: situations to avoid #38: "...and the dog was there too?"
|
|
|
|
|
I was sooooo close.
Sometimes it takes help from people willing to give it !!!
Thank you lauren
Paul
|
|
|
|
|
On a WinMe box, how can I disable system restore so that is stops adding *.cpy files into the _Restore directory?
|
|
|
|
|
I'm not in front of my Me machine, so this is from memory, but it should be:
System properties - Advanced tab - File System button - Disable System REstore checkbox.
--Mike--
Buy me stuff! (Link fixed now)
Like the Google toolbar? Then check out UltraBar, with more features & customizable search engines!
My really out-of-date homepage
Big fan of Alyson Hannigan and Jamie Salé.
Sonork - 100.10414 AcidHelm
|
|
|
|
|
It is already disabled. But the _Restore/Temp directory still keeps growing. I found out that if I set a new restore point, then the folder gets cleared, but is there a way to completely disable system restore?
|
|
|
|
|
Hey Guys
How do i check for whether an instance of my program is already running so that i can then stop another one being started.
Cheers Peter
|
|
|
|
|
There are many examples here at cp.com.
Just take a look at the articles and use the search engine
regards
modified 12-Sep-18 21:01pm.
|
|
|
|
|
I think one way is to use FindWindow() and use your window class,if it find it then do not attempt your application to proceed.
Mazy
"The path you tread is narrow and the drop is shear and very high,
The ravens all are watching from a vantage point near by,
Apprehension creeping like a choo-train uo your spine,
Will the tightrope reach the end;will the final cuplet rhyme?"Cymbaline-Pink Floyd
|
|
|
|
|
Short Solution – Use a mutex
Long Solution – Joe Newcomer’s brilliant article
The posting stats are now in PDF:-
http://www.busterboy.org/codeproject/
Feel free to make your comments.
Updated - May 04th, Saturday
|
|
|
|
|
See this article.
/ravi
"There is always one more bug..."
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
I want to know if there is any function like C function 'printf'.
For example, I just want to draw a line of text in the view like that:you have typed a %s.
in C ,I would do like that :printf("you have typed %s",str);
but I could not the function can do like this way(I know there is a function ,TRACE,but it is not I need) in MFC,could anybody answer me?
YES, I am here.
|
|
|
|
|
CString::Format();
- Anders
Money talks, but all mine ever says is "Goodbye!"
|
|
|
|
|
CString.Format(wada wada wada)
or
sprintf(wada wada wada)
then
TextOut(blah blah blah)
then apparently you will have an uncle called bob
situations to avoid #37: "good morning ... how many sugars do you take in your coffee ... and what was your name again?"
coming soon: situations to avoid #38: "...and the dog was there too?"
|
|
|
|
|
Can these functions write to the view?
YES, I am here.
|
|
|
|