 |
|
 |
Hi Don –
Thanks for writing the Code Project article on multi-monitor classes in February of 2003. I find that it is still relevant and useful today.
I am managing an open source project called TinyCAD, an electrical schematic capture program available on www.sourceforge.net. I have run into some problems in TinyCAD where it needs to know about multiple monitors and am planning to use your MFC wrapper classes to implement some bug fixes.
I have 2 questions:
1) Have you made any newer changes to MultiMon since you made the source available on Code Project, or any other classes or enhancements that I should know about before incorporating it into TinyCAD? Are there any limitations that you know of when used on Windows XP (any service pack) in conjunction with Microsoft Visual Studio 2003/2005/2008? I doubt that there are, but am just trying to be careful.
2) TinyCAD is licensed for free using the GNU LGPL license. I am not aware of any conflicts, but at the very least, out of courtesy, thought that I should inquire whether you are aware of any licensing conflicts that would prevent me from using your unchanged source in a GNU LGPL open source project?
TinyCAD gets between 100 and 200 downloads per day, so once I release the bug fix that will incorporate your Multimon classes, it will be next to impossible to stop its distribution. There are also other developers out there (mostly in non-English speaking countries) that get copies of the source as soon as I release it and then they re-release it in other languages (still under the LGPL license). I do not plan to make any changes to your original source, just simply incorporate it into TinyCAD’s fabric.
Thanks for your nice contribution to the open source community!
Best regards,
Don Lucas
|
|
|
|
 |
|
 |
Hey Don,
DonaldJLucas wrote: 1) Have you made any newer changes to MultiMon since you made the source available on Code Project, or any other classes or enhancements that I should know about before incorporating it into TinyCAD? Are there any limitations that you know of when used on Windows XP (any service pack) in conjunction with Microsoft Visual Studio 2003/2005/2008? I doubt that there are, but am just trying to be careful.
I haven't made any updates to this for quite some time. I have compiled it against the 2005 VC libraries for a side project so I don't believe there should be any issues with current versions of MFC (though I haven't looked at the latest releases of that framework). I don't know of any platform limitations but haven't tried this on Vista or Windows 7. I can't see any reason why it wouldn't work unless MSDN indicates specific changes to the underlying API.
As for the licensing: I picked the CPOL for no other reason than is seemed like a good one. I have absolutely no issue with you using this code however works best for your project (assuming I'm indemnified from liability if it causes global thermo nuclear war or brings down the internet ).
I don't know if there are specific incompatibilities between the CPOL and LGPL but from my perspective have at!
Don
10 PRINT Software is hard. - D Knuth
20 GOTO 10
|
|
|
|
 |
|
 |
Thanks, Don -
You didn't really give this project a name, other than the class names. I usually provide an attibution in TinyCAD's Help About dialog box for any other open source projects that have helped TinyCAD to accomplish its goals. Unless you suggest otherwise (or wish to remain less visible), I will attribute as follows:
"Don Kackman's MultiMon Multiple Monitor Support: CMonitor Class Version 1.0". This will be located in plain text on the Help About dialog box intermixed with other similar format attributions. Your copyright notices will only be visible to those users who choose to download the source files. We may improve this in the future, but for now, this is all that TinyCAD does (I am not the original author or manager of TinyCAD).
In addition, your original source publishes one of your older email addresses that is no longer valid. I will be happy to either update it with an address of your choice, delete the line containing the email address, or use a newly released set of sources from you, but I suggest that it not be released with a retired email address to avoid the "inquiring minds want to know" issue (isn't fame great?!!). Please advise how you would prefer for me to proceed.
Thanks,
Don Lucas
|
|
|
|
 |
|
 |
That all sounds good to me. You can use dkackman_2000 *at* yahoo *dot* com for my email.
I'll have to give TinyCad a look just out of curiosity.
10 PRINT Software is hard. - D Knuth
20 GOTO 10
|
|
|
|
 |
|
 |
I have written an application to display video. When running in a dual monitor system the video become black in one and available in other. Can any body pls send me ideas about this. Thanks in advance
|
|
|
|
 |
|
 |
Can you please post a vb.net or c# version please ?
|
|
|
|
 |
|
 |
All of this already part of the base class library in .net. Check out System.Windows.Forms.Screen.
|
|
|
|
 |
|
 |
Hi~I want to ask some question about MultiMonitor. I had used EnumDisplayDevices EnumDisplaySettings and ChangeDisplaySettingsEx extended desktop to secondary monitor, but still want to realize mirror display too. I think maybe you can help me. Would you please give me some direction? Thank you!
|
|
|
|
 |
|
 |
What are the basic things done to develeop a project using MFC classes? Sajin m k
|
|
|
|
 |
|
 |
For retrive bits per pixel for each monitor could be used EnumDisplaySettings() function :
DEVMODE dev;
BOOL res = ::EnumDisplaySettings( MonitorName, // get from MONITORINFOEX::szDevice
ENUM_CURRENT_SETTINGS,
&dev );
if (res) {
TRACE( "BPP for %-s is %-d\n", MonitorName, dev.dmBitsPerPel );
}
|
|
|
|
 |
|
 |
If I understand what you're getting at take a look at the implementation of CMonitor::GetBitsPerPixel and CMonitor::CreateDC. You'll see that the value reported is specific to the HMONITOR wrapped by a particular instance of CMonitor.
HDC CMonitor::CreateDC() const
{
ASSERT( IsMonitor() );
CString name;
GetName( name );
HDC hdc = ::CreateDC( name, name, NULL, NULL );
ASSERT( hdc != NULL );
CRect rect;
GetMonitorRect( &rect );
::SetViewportOrgEx( hdc, -rect.left, -rect.top, NULL );
::SetViewportExtEx( hdc, rect.Width(), rect.Height(), NULL );
return hdc;
}
int CMonitor::GetBitsPerPixel() const
{
HDC hdc = CreateDC();
int ret = ::GetDeviceCaps( hdc, BITSPIXEL ) * ::GetDeviceCaps( hdc, PLANES );
VERIFY( ::DeleteDC( hdc ) );
return ret;
}
|
|
|
|
 |
|
 |
One problem - the monitors could have the different bits-per-pixel values. And I didn't find the way how to solve it ;(
|
|
|
|
 |
|
 |
I am writing a program for a Scoreboard that contains a SplitterWnd, the upper Window (ScoreboardWnd) displays the whole screen with (Period Time, Scores, .. etc). The lower window contains all the Input’s and Buttons to administrate the Scoreboard.
I now want to display only the ScoreboardWnd on another VGA screen (Full mode).
I have looked at the CMonitor class and tested it properly.
On a Laptop with a 2nd VGA out I connected a 2nd TFT screen to see how the program works.
Now a few questions: How can I display out from a SplitterWnd a window on the 2nd screen?
On the laptop the whole program should be displayed.
The program is made with VC 7.xx!
It would be great if you have a sample for such a case I described above. Great work by the way!
Thanks in advance
Best regards
Karl
|
|
|
|
 |
|
 |
These are very useful classes, but there is one problem. In Monitors.cpp, you assume that GetSystemMetrics(SM_CMONITORS) will return the number of monitors that EnumDisplayMonitors() will enumerate. This is usually correct, but not always. I am working on a Win2000 system where GetSystemMetrics returns 1, but EnumDisplayMonitors finds 2! When this happens, the line
pAddMonitor->pMonitors->SetAt( pAddMonitor->currentIndex, pMonitor ); will assert, because currentIndex will be greater than the array size.
I believe the reason for this is what MSDN refers to as "invisible pseudo-monitors associated with mirroring drivers". To avoid this problem, you can use the EnumDisplayDevices() API, where you can explicitly test for the flag DISPLAY_DEVICE_MIRRORING_DRIVER.
|
|
|
|
 |
|
 |
Hmmm. Thanks for the heads up. I wasn't aware of the existence of "invisible pseudo-monitors"
I'll post a fix when I get a chance.
|
|
|
|
 |
|
 |
This may not be a complete fix, but at least it keeps the app from crashing:
static BOOL CALLBACK AddMonitorsCallBack(HMONITOR hMonitor,
HDC ,
LPRECT ,
LPARAM dwData )
{
LPADDMONITOR pAddMonitor = (LPADDMONITOR)dwData;
CMonitor* pMonitor = new CMonitor;
pMonitor->Attach( hMonitor );
if (pAddMonitor->currentIndex < pAddMonitor->pMonitors->GetSize())
{
pAddMonitor->pMonitors->SetAt( pAddMonitor->currentIndex, pMonitor );
pAddMonitor->currentIndex++;
}
return TRUE;
}
|
|
|
|
 |
|
 |
How about using SetAtGrow ?
pAddMonitor->pMonitors->SetAtGrow( pAddMonitor->currentIndex, pMonitor );
MSDN Remarks
Sets the array element at the specified index. The array grows automatically if necessary (that is, the upper bound is adjusted to accommodate the new element).
|
|
|
|
 |
|
 |
Does anybody have any ideas or code as to how to programmatically turn off and on the second monitor?
|
|
|
|
 |
|
 |
i already include the CMonitor class...but still it is not defined....can u please help me...i try to find the documentation of this class..but failed...
error C2079: 'monitor' uses undefined class 'CMonitor'
|
|
|
|
 |
|
 |
Have you
#include "MultiMonitor.h"
#include "Monitors.h"
in the cpp where you are using these classes?
|
|
|
|
 |
|
 |
sorry..i missed the #include "MultiMonitor.h"...thanks...
|
|
|
|
 |
|
 |
When the test application has MFC statically linked in, the following errors are produced:
Linking...
nafxcwd.lib(wincore.obj) : error LNK2005: _g_fMultimonPlatformNT already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _g_fMultiMonInitDone already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _g_pfnEnumDisplayDevices already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _g_pfnEnumDisplayMonitors already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _g_pfnGetMonitorInfo already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _g_pfnMonitorFromPoint already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _g_pfnMonitorFromRect already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _g_pfnMonitorFromWindow already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _g_pfnGetSystemMetrics already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _IsPlatformNT already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _InitMultipleMonitorStubs already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _xGetSystemMetrics@4 already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _xMonitorFromPoint@12 already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _xMonitorFromRect@8 already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _xMonitorFromWindow@8 already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _xGetMonitorInfo@8 already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _xEnumDisplayMonitors@16 already defined in Multimon.obj
nafxcwd.lib(wincore.obj) : error LNK2005: _xEnumDisplayDevices@16 already defined in Multimon.obj
Debug/MonitorTest.exe : fatal error LNK1169: one or more multiply defined symbols found
Do you know of a way around this (except of course using run time binding )?
Terry
|
|
|
|
 |
|
 |
The code for Multimon.obj is being linked in more than once. I haven't looked at the code but if it is C code you might need extern defs.
Neville Franks, Author of ED for Windows www.getsoft.com and coming soon: Surfulater www.surfulater.com
|
|
|
|
 |
|
 |
Same problem in placing in a static/multithread app, simply exclude the offending libaries till the problem goes away (honest !)
For example exclude nafxcwd.lib - done in MSDEV in the link input option in Project settings
Bob
|
|
|
|
 |
|
 |
just move the #include "multimon.h" to BalloonHelp.h
Lee.
|
|
|
|
 |