diff --git a/dlls/strmbase/Makefile.in b/dlls/strmbase/Makefile.in index 07ac5a00b67..06654abaa76 100644 --- a/dlls/strmbase/Makefile.in +++ b/dlls/strmbase/Makefile.in @@ -10,6 +10,7 @@ C_SRCS = \ pospass.c \ qualitycontrol.c \ seeking.c \ - transform.c + transform.c \ + window.c @MAKE_IMPLIB_RULES@ diff --git a/dlls/strmbase/window.c b/dlls/strmbase/window.c new file mode 100644 index 00000000000..3a90e78e400 --- /dev/null +++ b/dlls/strmbase/window.c @@ -0,0 +1,146 @@ +/* + * Generic Implementation of strmbase window classes + * + * Copyright 2012 Aric Stewart, CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "dshow.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/strmbase.h" +#include "uuids.h" +#include "vfwmsgs.h" +#include + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +static LRESULT CALLBACK WndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + BaseWindow* This = (BaseWindow*)GetWindowLongPtrW(hwnd, 0); + + if (!This) + return DefWindowProcW(hwnd, uMsg, wParam, lParam); + + if (This->pFuncsTable->pfnOnReceiveMessage) + return This->pFuncsTable->pfnOnReceiveMessage(This, hwnd, uMsg, wParam, lParam); + else + return BaseWindowImpl_OnReceiveMessage(This, hwnd, uMsg, wParam, lParam); +} + +LRESULT WINAPI BaseWindowImpl_OnReceiveMessage(BaseWindow *This, HWND hwnd, INT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (This->pFuncsTable->pfnPossiblyEatMessage && This->pFuncsTable->pfnPossiblyEatMessage(This, uMsg, wParam, lParam)) + return 0; + + switch (uMsg) + { + case WM_SIZE: + if (This->pFuncsTable->pfnOnSize) + return This->pFuncsTable->pfnOnSize(This, LOWORD(lParam), HIWORD(lParam)); + else + return BaseWindowImpl_OnSize(This, LOWORD(lParam), HIWORD(lParam)); + } + + return DefWindowProcW(hwnd, uMsg, wParam, lParam); +} + +BOOL WINAPI BaseWindowImpl_OnSize(BaseWindow *This, LONG Width, LONG Height) +{ + This->Width = Width; + This->Height = Height; + return TRUE; +} + +HRESULT WINAPI BaseWindow_Init(BaseWindow *pBaseWindow, const BaseWindowFuncTable* pFuncsTable) +{ + if (!pFuncsTable) + return E_INVALIDARG; + + ZeroMemory(pBaseWindow,sizeof(BaseWindow)); + pBaseWindow->pFuncsTable = pFuncsTable; + + return S_OK; +} + +HRESULT WINAPI BaseWindow_Destroy(BaseWindow *This) +{ + if (This->hWnd) + BaseWindowImpl_DoneWithWindow(This); + + HeapFree(GetProcessHeap(), 0, This); + return S_OK; +} + +HRESULT WINAPI BaseWindowImpl_PrepareWindow(BaseWindow *This) +{ + WNDCLASSW winclass; + static const WCHAR windownameW[] = { 'A','c','t','i','v','e','M','o','v','i','e',' ','W','i','n','d','o','w',0 }; + + This->pClassName = This->pFuncsTable->pfnGetClassWindowStyles(This, &This->ClassStyles, &This->WindowStyles, &This->WindowStylesEx); + + winclass.style = This->ClassStyles; + winclass.lpfnWndProc = WndProcW; + winclass.cbClsExtra = 0; + winclass.cbWndExtra = sizeof(BaseWindow*); + winclass.hInstance = This->hInstance; + winclass.hIcon = NULL; + winclass.hCursor = NULL; + winclass.hbrBackground = GetStockObject(BLACK_BRUSH); + winclass.lpszMenuName = NULL; + winclass.lpszClassName = This->pClassName; + if (!RegisterClassW(&winclass) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) + { + ERR("Unable to register window class: %u\n", GetLastError()); + return E_FAIL; + } + + This->hWnd = CreateWindowExW(This->WindowStylesEx, + This->pClassName, windownameW, + This->WindowStyles, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, NULL, NULL, This->hInstance, + NULL); + + if (!This->hWnd) + { + ERR("Unable to create window\n"); + return E_FAIL; + } + + SetWindowLongPtrW(This->hWnd, 0, (LONG_PTR)This); + + This->hDC = GetDC(This->hWnd); + + return S_OK; +} + +HRESULT WINAPI BaseWindowImpl_DoneWithWindow(BaseWindow *This) +{ + if (!This->hWnd) + return S_OK; + + if (This->hDC) + ReleaseDC(This->hWnd, This->hDC); + This->hDC = NULL; + + DestroyWindow(This->hWnd); + This->hWnd = NULL; + + return S_OK; +} diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 4944e349751..f5aac5cdf63 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -391,6 +391,44 @@ VOID WINAPI OutputQueue_EOS(OutputQueue *pOutputQueue); VOID WINAPI OutputQueue_SendAnyway(OutputQueue *pOutputQueue); DWORD WINAPI OutputQueueImpl_ThreadProc(OutputQueue *pOutputQueue); +typedef struct tagBaseWindow +{ + HWND hWnd; + LONG Width; + LONG Height; + HINSTANCE hInstance; + LPWSTR pClassName; + DWORD ClassStyles; + DWORD WindowStyles; + DWORD WindowStylesEx; + HDC hDC; + + const struct BaseWindowFuncTable* pFuncsTable; +} BaseWindow; + +typedef LPWSTR (WINAPI *BaseWindow_GetClassWindowStyles)(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx); +typedef BOOL (WINAPI *BaseWindow_PossiblyEatMessage)(BaseWindow *This, UINT uMsg, WPARAM wParam, LPARAM lParam); +typedef LRESULT (WINAPI *BaseWindow_OnReceiveMessage)(BaseWindow *This, HWND hwnd, INT uMsg, WPARAM wParam, LPARAM lParam); +typedef BOOL (WINAPI *BaseWindow_OnSize)(BaseWindow *This, LONG Height, LONG Width); + +typedef struct BaseWindowFuncTable +{ + /* Required */ + BaseWindow_GetClassWindowStyles pfnGetClassWindowStyles; + /* Optional, WinProc Related */ + BaseWindow_OnReceiveMessage pfnOnReceiveMessage; + BaseWindow_PossiblyEatMessage pfnPossiblyEatMessage; + BaseWindow_OnSize pfnOnSize; +} BaseWindowFuncTable; + +HRESULT WINAPI BaseWindow_Init(BaseWindow *pBaseWindow, const BaseWindowFuncTable* pFuncsTable); +HRESULT WINAPI BaseWindow_Destroy(BaseWindow *pBaseWindow); + +HRESULT WINAPI BaseWindowImpl_PrepareWindow(BaseWindow *This); +HRESULT WINAPI BaseWindowImpl_DoneWithWindow(BaseWindow *This); +LRESULT WINAPI BaseWindowImpl_OnReceiveMessage(BaseWindow *This, HWND hwnd, INT uMsg, WPARAM wParam, LPARAM lParam); +BOOL WINAPI BaseWindowImpl_OnSize(BaseWindow *This, LONG Height, LONG Width); + /* Dll Functions */ BOOL WINAPI STRMBASE_DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv); HRESULT WINAPI STRMBASE_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);