Fix major DC suckage on win2k and 98. Instead of calling GetDC all the time,

only call it when we need it and then be sure to release it. r=mjudge, bug#49285
This commit is contained in:
pinkerton%netscape.com 2000-09-14 23:53:19 +00:00
Родитель 6c1873e996
Коммит a163e487b1
4 изменённых файлов: 30 добавлений и 22 удалений

Просмотреть файл

@ -107,7 +107,7 @@ NS_IMPL_ISUPPORTS(nsScreenManagerWin, NS_GET_IID(nsIScreenManager))
// screen. This should change when a multi-monitor impl is done. // screen. This should change when a multi-monitor impl is done.
// //
nsIScreen* nsIScreen*
nsScreenManagerWin :: CreateNewScreenObject ( HDC inContext, void* inScreen ) nsScreenManagerWin :: CreateNewScreenObject ( void* inScreen )
{ {
nsIScreen* retScreen = nsnull; nsIScreen* retScreen = nsnull;
@ -121,7 +121,7 @@ nsScreenManagerWin :: CreateNewScreenObject ( HDC inContext, void* inScreen )
} }
} // for each screen. } // for each screen.
retScreen = new nsScreenWin(inContext, inScreen); retScreen = new nsScreenWin(inScreen);
ScreenListItem* listItem = new ScreenListItem ( (HMONITOR)inScreen, retScreen ); ScreenListItem* listItem = new ScreenListItem ( (HMONITOR)inScreen, retScreen );
mScreenList.AppendElement ( listItem ); mScreenList.AppendElement ( listItem );
@ -144,7 +144,7 @@ nsScreenManagerWin :: ScreenForRect ( PRInt32 inLeft, PRInt32 inTop, PRInt32 inW
{ {
if ( !(inWidth || inHeight) ) { if ( !(inWidth || inHeight) ) {
NS_WARNING ( "trying to find screen for sizeless window, using primary monitor" ); NS_WARNING ( "trying to find screen for sizeless window, using primary monitor" );
*outScreen = CreateNewScreenObject ( ::GetDC(nsnull), nsnull ); // addrefs *outScreen = CreateNewScreenObject ( nsnull ); // addrefs
return NS_OK; return NS_OK;
} }
@ -161,7 +161,7 @@ nsScreenManagerWin :: ScreenForRect ( PRInt32 inLeft, PRInt32 inTop, PRInt32 inW
} }
#endif #endif
*outScreen = CreateNewScreenObject ( ::GetDC(nsnull), genScreen ); // addrefs *outScreen = CreateNewScreenObject ( genScreen ); // addrefs
return NS_OK; return NS_OK;
@ -177,7 +177,7 @@ nsScreenManagerWin :: ScreenForRect ( PRInt32 inLeft, PRInt32 inTop, PRInt32 inW
NS_IMETHODIMP NS_IMETHODIMP
nsScreenManagerWin :: GetPrimaryScreen(nsIScreen** aPrimaryScreen) nsScreenManagerWin :: GetPrimaryScreen(nsIScreen** aPrimaryScreen)
{ {
*aPrimaryScreen = CreateNewScreenObject ( ::GetDC(nsnull), nsnull ); // addrefs *aPrimaryScreen = CreateNewScreenObject ( nsnull ); // addrefs
return NS_OK; return NS_OK;
} // GetPrimaryScreen } // GetPrimaryScreen

Просмотреть файл

@ -45,7 +45,7 @@ public:
private: private:
nsIScreen* CreateNewScreenObject ( HDC inContext, void* inScreen ) ; nsIScreen* CreateNewScreenObject ( void* inScreen ) ;
PRBool mHasMultiMonitorAPIs; PRBool mHasMultiMonitorAPIs;
PRUint32 mNumberOfScreens; PRUint32 mNumberOfScreens;

Просмотреть файл

@ -45,15 +45,19 @@ typedef BOOL (WINAPI *GetMonitorInfoProc)(HMONITOR inMon, LPMONITORINFO ioInfo);
#endif #endif
nsScreenWin :: nsScreenWin ( HDC inContext, void* inScreen ) nsScreenWin :: nsScreenWin ( void* inScreen )
: mContext(inContext), mScreen(inScreen), mHasMultiMonitorAPIs(PR_FALSE), : mScreen(inScreen), mHasMultiMonitorAPIs(PR_FALSE),
mGetMonitorInfoProc(nsnull) mGetMonitorInfoProc(nsnull)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
NS_ASSERTION ( inContext, "Passing null device to nsScreenWin" ); #ifdef DEBUG
NS_ASSERTION ( ::GetDeviceCaps(inContext, TECHNOLOGY) == DT_RASDISPLAY, "Not a display screen"); HDC hDCScreen = ::GetDC(nsnull);
NS_ASSERTION(hDCScreen,"GetDC Failure");
NS_ASSERTION ( ::GetDeviceCaps(hDCScreen, TECHNOLOGY) == DT_RASDISPLAY, "Not a display screen");
::ReleaseDC(nsnull,hDCScreen);
#endif
#if _MSC_VER >= 1200 #if _MSC_VER >= 1200
// figure out if we can call the multiple monitor APIs that are only // figure out if we can call the multiple monitor APIs that are only
// available on Win98/2000. // available on Win98/2000.
@ -101,11 +105,15 @@ nsScreenWin :: GetRect(PRInt32 *outLeft, PRInt32 *outTop, PRInt32 *outWidth, PRI
} }
#endif #endif
if (!success) { if (!success) {
*outTop = *outLeft = 0; HDC hDCScreen = ::GetDC(nsnull);
*outWidth = ::GetDeviceCaps(mContext, HORZRES); NS_ASSERTION(hDCScreen,"GetDC Failure");
*outHeight = ::GetDeviceCaps(mContext, VERTRES);
*outTop = *outLeft = 0;
*outWidth = ::GetDeviceCaps(hDCScreen, HORZRES);
*outHeight = ::GetDeviceCaps(hDCScreen, VERTRES);
::ReleaseDC(nsnull, hDCScreen);
} }
return NS_OK; return NS_OK;
} // GetRect } // GetRect
@ -148,7 +156,12 @@ NS_IMETHODIMP
nsScreenWin :: GetPixelDepth(PRInt32 *aPixelDepth) nsScreenWin :: GetPixelDepth(PRInt32 *aPixelDepth)
{ {
//XXX not sure how to get this info for multiple monitors, this might be ok... //XXX not sure how to get this info for multiple monitors, this might be ok...
*aPixelDepth = ::GetDeviceCaps(mContext, BITSPIXEL); HDC hDCScreen = ::GetDC(nsnull);
NS_ASSERTION(hDCScreen,"GetDC Failure");
*aPixelDepth = ::GetDeviceCaps(hDCScreen, BITSPIXEL);
::ReleaseDC(nsnull, hDCScreen);
return NS_OK; return NS_OK;
} // GetPixelDepth } // GetPixelDepth

Просмотреть файл

@ -31,24 +31,19 @@
class nsScreenWin : public nsIScreen class nsScreenWin : public nsIScreen
{ {
public: public:
nsScreenWin ( HDC inContext, void* inScreen ); nsScreenWin ( void* inScreen );
~nsScreenWin(); ~nsScreenWin();
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSISCREEN NS_DECL_NSISCREEN
private: private:
// are we the primary screen? Needed so we can sub out the menubar if
// asked.
//PRBool IsPrimaryScreen ( ) const { return (mScreen == ::GetMainDevice()); }
// function pointers for multi-monitor API system calls that we use. Not // function pointers for multi-monitor API system calls that we use. Not
// valid unless |mHasMultiMonitorAPIs| is true // valid unless |mHasMultiMonitorAPIs| is true
PRBool mHasMultiMonitorAPIs; PRBool mHasMultiMonitorAPIs;
FARPROC mGetMonitorInfoProc ; FARPROC mGetMonitorInfoProc ;
HDC mContext; // the dc that represents this screen
void* mScreen; // a |HMONITOR|, can't use this type in header file though. void* mScreen; // a |HMONITOR|, can't use this type in header file though.
}; };