📄 winutil.cpp
字号:
CBaseWindow *pBaseWindow = (CBaseWindow *)GetWindowLong(hwnd,0);
if (pBaseWindow == NULL) {
// Get the structure pointer from the create struct.
// We can only do this for WM_NCCREATE which should be one of
// the first messages we receive. Anything before this will
// have to be passed to DefWindowProc (i.e. WM_GETMINMAXINFO)
// If the message is WM_NCCREATE we set our pBaseWindow pointer
// and will then place it in the window structure
#ifndef UNDER_CE
if ((uMsg != WM_NCCREATE)
|| (NULL == (pBaseWindow = *(CBaseWindow**) ((LPCREATESTRUCT)lParam)->lpCreateParams)))
#else
if ((uMsg != WM_CREATE)
|| (NULL == (pBaseWindow = *(CBaseWindow**) ((LPCREATESTRUCT)lParam)->lpCreateParams)))
#endif // UNDER_CE
{
return(DefWindowProc(hwnd, uMsg, wParam, lParam));
}
// Set the window LONG to be the object who created us
#ifdef DEBUG
SetLastError(0); // because of the way SetWindowLong works
#endif
BOOL rc = SetWindowLong(hwnd, (DWORD) 0, (LONG) pBaseWindow);
#ifdef DEBUG
if (0 == rc) {
// SetWindowLong MIGHT have failed. (Read the docs which admit
// that it is awkward to work out if you have had an error.)
LONG lasterror = GetLastError();
ASSERT(0 == lasterror);
// If this is not the case we have not set the pBaseWindow pointer
// into the window structure and we will blow up.
}
#endif
}
// See if this is the packet of death
if (uMsg == MsgDestroy && uMsg != 0) {
pBaseWindow->DoneWithWindow();
return 0;
}
return pBaseWindow->OnReceiveMessage(hwnd,uMsg,wParam,lParam);
}
// When the window size changes we adjust our member variables that
// contain the dimensions of the client rectangle for our window so
// that we come to render an image we will know whether to stretch
BOOL CBaseWindow::OnSize(LONG Width, LONG Height)
{
#ifdef WINUTIL_STUB
STUBRET(FALSE);
#else
m_Width = Width;
m_Height = Height;
return TRUE;
#endif // WINUTIL_STUB
}
// This function handles the WM_CLOSE message
BOOL CBaseWindow::OnClose()
{
#ifdef WINUTIL_STUB
STUBRET(FALSE);
#else
ShowWindow(m_hwnd,SW_HIDE);
return TRUE;
#endif // WINUTIL_STUB
}
// This is called by the worker window thread when it receives a terminate
// message from the window object destructor to delete all the resources we
// allocated during initialisation. By the time the worker thread exits all
// processing will have been completed as the source filter disconnection
// flushes the image pending sample, therefore the GdiFlush should succeed
HRESULT CBaseWindow::UninitialiseWindow()
{
// Have we already cleaned up
if (m_hwnd == NULL) {
ASSERT(m_hdc == NULL);
ASSERT(m_MemoryDC == NULL);
return NOERROR;
}
// Release the window resources
#ifndef UNDER_CE
EXECUTE_ASSERT(GdiFlush());
#endif // UNDER_CE
if (m_hdc)
{
EXECUTE_ASSERT(ReleaseDC(m_hwnd,m_hdc));
m_hdc = NULL;
}
#ifndef WINUTIL_STUB
if (m_MemoryDC)
{
EXECUTE_ASSERT(DeleteDC(m_MemoryDC));
m_MemoryDC = NULL;
}
#endif // WINUTIL_STUB
// Reset the window variables
m_hwnd = NULL;
return NOERROR;
}
// This is called by the worker window thread after it has created the main
// window and it wants to initialise the rest of the owner objects window
// variables such as the device contexts. We execute this function with the
// critical section still locked. Nothing in this function must generate any
// SendMessage calls to the window because this is executing on the window
// thread so the message will never be processed and we will deadlock
HRESULT CBaseWindow::InitialiseWindow(HWND hwnd)
{
// Initialise the window variables
ASSERT(IsWindow(hwnd));
m_hwnd = hwnd;
if (m_bDoGetDC)
{
EXECUTE_ASSERT(m_hdc = GetDC(hwnd));
#ifndef WINUTIL_STUB
EXECUTE_ASSERT(SetStretchBltMode(m_hdc,COLORONCOLOR));
EXECUTE_ASSERT(m_MemoryDC = CreateCompatibleDC(m_hdc));
EXECUTE_ASSERT(SetStretchBltMode(m_MemoryDC,COLORONCOLOR));
#endif // WINUTIL_STUB
}
return NOERROR;
}
HRESULT CBaseWindow::DoCreateWindow()
{
WNDCLASS wndclass; // Used to register classes
BOOL bRegistered; // Is this class registered
HWND hwnd; // Handle to our window
bRegistered = GetClassInfo(m_hInstance, // Module instance
m_pClassName, // Window class
&wndclass); // Info structure
// if the window is to be used for drawing puposes and we are getting a DC
// for the entire lifetime of the window then changes the class style to do
// say so. If we don't set this flag then the DC comes from the cache and is
// really bad.
if (m_bDoGetDC)
{
#ifndef UNDER_CE
m_ClassStyles |= CS_OWNDC;
#endif // UNDER_CE
}
// NOTE: Registered class names are scoped by process, so if quartz gets
// un/reloaded into a different spot (in the lifetime of host process), we must un/reregister
// the wndclass with new WndProc location. Can't directly compare wndclass.lpfnWndProc and
// WndProc, as prior is mapped into kernel addr space, so always try to UnregisterClass if class
// is registered.
if (!bRegistered || UnregisterClass(m_pClassName, m_hInstance)) {
// Register the renderer window class
wndclass.lpszClassName = m_pClassName;
wndclass.style = m_ClassStyles;
wndclass.lpfnWndProc = (WNDPROC) WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = sizeof(CBaseWindow *);
wndclass.hInstance = m_hInstance;
wndclass.hIcon = NULL;
#ifdef WINUTIL_STUB
wndclass.hCursor = NULL;
#else
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
#endif
wndclass.hbrBackground = (HBRUSH) NULL;
wndclass.lpszMenuName = NULL;
RegisterClass(&wndclass);
}
// Create the frame window. Pass the pBaseWindow information in the
// CreateStruct which allows our message handling loop to get hold of
// the pBaseWindow pointer.
CBaseWindow *pBaseWindow = this; // The owner window object
hwnd = CreateWindowEx(m_WindowStylesEx, // Extended styles
m_pClassName, // Registered name
TEXT("ActiveMovie Window"), // Window title
m_WindowStyles, // Window styles
CW_USEDEFAULT, // Start x position
CW_USEDEFAULT, // Start y position
DEFWIDTH, // Window width
DEFHEIGHT, // Window height
NULL, // Parent handle
NULL, // Menu handle
m_hInstance, // Instance handle
&pBaseWindow); // Creation data
// If we failed signal an error to the object constructor (based on the
// last Win32 error on this thread) then signal the constructor thread
// to continue, release the mutex to let others have a go and exit
if (hwnd == NULL) {
DWORD Error = GetLastError();
return HRESULT_FROM_WIN32(Error);
}
// Check the window LONG is the object who created us
ASSERT(GetWindowLong(hwnd, 0) == (LONG)this);
// Initialise the window and then signal the constructor so that it can
// continue and then finally unlock the object's critical section. The
// window class is left registered even after we terminate the thread
// as we don't know when the last window has been closed. So we allow
// the operating system to free the class resources as appropriate
InitialiseWindow(hwnd);
DbgLog((LOG_TRACE, 2, TEXT("Created window class (%s) HWND(%8.8X)"),
m_pClassName, hwnd));
return S_OK;
}
// The base class provides some default handling and calls DefWindowProc
LRESULT CBaseWindow::OnReceiveMessage(HWND hwnd, // Window handle
UINT uMsg, // Message ID
WPARAM wParam, // First parameter
LPARAM lParam) // Other parameter
{
ASSERT(IsWindow(hwnd));
if (PossiblyEatMessage(uMsg, wParam, lParam))
return 0;
// This is sent by the IVideoWindow SetWindowForeground method. If the
// window is invisible we will show it and make it topmost without the
// foreground focus. If the window is visible it will also be made the
// topmost window without the foreground focus. If wParam is TRUE then
// for both cases the window will be forced into the foreground focus
#ifndef WINUTIL_STUB
if (uMsg == m_ShowStageMessage) {
BOOL bVisible = IsWindowVisible(hwnd);
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW |
(bVisible ? SWP_NOACTIVATE : 0));
#ifdef BUGBUG
// Should we bring the window to the foreground
if (wParam == TRUE) {
SetForegroundWindow(hwnd);
}
#else
SetForegroundWindow(hwnd);
// Should we give the window focus
if (wParam == TRUE) {
SetFocus(hwnd);
}
#endif
return (LRESULT) 1;
}
// When we go fullscreen we have to add the WS_EX_TOPMOST style to the
// video window so that it comes out above any task bar (this is more
// relevant to WindowsNT than Windows95). However the SetWindowPos call
// must be on the same thread as that which created the window. The
// wParam parameter can be TRUE or FALSE to set and reset the topmost
if (uMsg == m_ShowStageTop) {
HWND HwndTop = (wParam == TRUE ? HWND_TOPMOST : HWND_NOTOPMOST);
BOOL bVisible = IsWindowVisible(hwnd);
SetWindowPos(hwnd, HwndTop, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE |
(wParam == TRUE ? SWP_SHOWWINDOW : 0) |
(bVisible ? SWP_NOACTIVATE : 0));
return (LRESULT) 1;
}
// New palette stuff
if (uMsg == m_RealizePalette) {
ASSERT(m_hwnd == hwnd);
return OnPaletteChange(m_hwnd,WM_QUERYNEWPALETTE);
}
#endif // WINUTIL_STUB
switch (uMsg) {
#ifndef WINUTIL_STUB
case WM_SETTINGCHANGE:
if (SETTINGCHANGE_RESET == wParam && 0 == lParam) {
DeleteDC(m_MemoryDC);
ReleaseDC(hwnd, m_hdc);
m_hdc = GetDC(hwnd);
m_MemoryDC = CreateCompatibleDC(m_hdc);
}
return (LRESULT) 0;
#endif // WINUTIL_STUB
// Repaint the window if the system colours change
case WM_SYSCOLORCHANGE:
InvalidateRect(hwnd,NULL,FALSE);
return (LRESULT) 1;
// Somebody has changed the palette
case WM_PALETTECHANGED:
OnPaletteChange((HWND)wParam,uMsg);
return (LRESULT) 0;
// We are about to receive the keyboard focus so we ask GDI to realise
// our logical palette again and hopefully it will be fully installed
// without any mapping having to be done during any picture rendering
case WM_QUERYNEWPALETTE:
ASSERT(m_hwnd == hwnd);
return OnPaletteChange(m_hwnd,uMsg);
// Store the width and height as useful base class members
case WM_SIZE:
OnSize(LOWORD(lParam), HIWORD(lParam));
return (LRESULT) 0;
// Intercept the WM_CLOSE messages to hide the window
case WM_CLOSE:
OnClose();
return (LRESULT) 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
// This handles the Windows palette change messages - if we do realise our
// palette then we return TRUE otherwise we return FALSE. If our window is
// foreground application then we should get first choice of colours in the
// system palette entries. We get best performance when our logical palette
// includes the standard VGA colours (at the beginning and end) otherwise
// GDI may have to map from our palette to the device palette while drawing
LRESULT CBaseWindow::OnPaletteChange(HWND hwnd,UINT Message)
{
#ifdef WINUTIL_STUB
STUBFAIL;
#else
// First check we are not changing the palette during closedown
if (m_hwnd == NULL || hwnd == NULL) {
return (LRESULT) 0;
}
ASSERT(!m_bRealizing);
// Should we realise our palette again
if ((Message == WM_QUERYNEWPALETTE || hwnd != m_hwnd)) {
// It seems that even if we're invisible that we can get asked
// to realize our palette and this can cause really ugly side-effects
if (!IsWindowVisible(m_hwnd)) {
DbgLog((LOG_TRACE, 1, TEXT("Realizing when invisible!")));
return (LRESULT) 0;
}
// Avoid recursion with multiple graphs in the same app
#ifdef DEBUG
m_bRealizing = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -