最近打算写一个播放器,很长时间没有接触过Win32编程,周末对Win32窗体程序做了一次回炉,编写自己窗体CODE记录下来,有很多不正确的地方希望得倒大家可以留言告诉我。后期会添加Opengl方面的支持。
该播放器可以支持多路视频,可以在多个屏幕被任意拖动,没有标题拦, 提供鼠标右键关闭菜单。
#include "stdafx.h"
#include "WindowsOpengl.h"
#include <atomic>
HWND winHandle;
HWND subWinHandle;
POINT pointDown;
POINT pointUp;
HINSTANCE hInst;
RECT clientRect;
WCHAR szTitle[MAX_PATH] = TEXT("CaptionOpengl");
WCHAR szWindowClass[MAX_PATH] = TEXT("CaptionClass");
WCHAR subTitle[MAX_PATH] = TEXT("SubCaptionOpengl");
WCHAR subWindowClass[MAX_PATH] = TEXT("SubCaptionClass");
std::atomic<bool> winLoadBk = false;
std::atomic<bool> subWinLoadBk = false;
BOOL InitInstance(HINSTANCE, int);
ATOM ParentRegisterClass(HINSTANCE hInstance);
ATOM ChildRegisterClass(HINSTANCE hInstance);
LRESULT CALLBACK ParentWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
#define ITEM_MENU_SCREEN_1 40001
#define ITEM_MENU_SCREEN_2 40002
#define ITEM_MENU_SCREEN_3 40003
#define ITEM_MENU_SCREEN_4 40004
#define ITEM_MENU_STOP_PLAY 40005
#define ITEM_MENU_START_PLAY 40006
#define ITEM_MENU_SET_PLAY 40007
#define ITEM_MENU_QUIT_PLAY 40008
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
ParentRegisterClass(hInstance);
ChildRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
MSG msg;
while(true)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT) {
break;
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return (int) msg.wParam;
}
ATOM ParentRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | WS_EX_TOOLWINDOW;
wcex.lpfnWndProc = ParentWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
wcex.lpszMenuName = NULL;
wcex.hIcon = NULL;
return RegisterClassExW(&wcex);
}
ATOM ChildRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | WS_EX_TOOLWINDOW;
wcex.lpfnWndProc = ChildWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszClassName = subWindowClass;
wcex.hIconSm = NULL;
wcex.lpszMenuName = NULL;;
wcex.hIcon = NULL;
return RegisterClassExW(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance;
winHandle = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW&(~WS_THICKFRAME),
0, 0, 800, 600, nullptr, nullptr, hInstance, nullptr);
if (!winHandle) return FALSE;
ShowWindow(winHandle, nCmdShow);
UpdateWindow(winHandle);
//subWinHandle = CreateWindow(subWindowClass, subTitle,
// WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE | WS_POPUP, 0, 0, 400, 200,
// winHandle, NULL, hInst, NULL);
subWinHandle = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW&(~WS_THICKFRAME),
300, 300, 800, 600, nullptr, nullptr, hInstance, nullptr);
if (!subWinHandle) return FALSE;
ShowWindow(subWinHandle, SW_SHOW);
return TRUE;
}
class WinPopMenu
{
HMENU m_pPopMenu;
public:
WinPopMenu()
{
m_pPopMenu = CreatePopupMenu();
if (m_pPopMenu)
{
HMENU Submenu = ::CreatePopupMenu();
::InsertMenu(m_pPopMenu, (-1), MF_BYPOSITION, ITEM_MENU_SCREEN_1 , TEXT("Screen - 1"));
::InsertMenu(m_pPopMenu, (-1), MF_BYPOSITION, ITEM_MENU_SCREEN_2 , TEXT("Screen - 2"));
::InsertMenu(m_pPopMenu, (-1), MF_BYPOSITION, ITEM_MENU_SCREEN_3 , TEXT("Screen - 3"));
::InsertMenu(m_pPopMenu, (-1), MF_BYPOSITION, ITEM_MENU_SCREEN_4 , TEXT("Screen - 4"));
::InsertMenu(m_pPopMenu, (-1), MF_BYPOSITION | MF_POPUP, (unsigned int)Submenu, TEXT("Play"));
::InsertMenu(Submenu , (-1), MF_BYPOSITION | MF_POPUP, ITEM_MENU_STOP_PLAY , TEXT("Stop"));
::InsertMenu(Submenu , (-1), MF_BYPOSITION | MF_POPUP, ITEM_MENU_START_PLAY, TEXT("Start"));
::InsertMenu(Submenu , (-1), MF_BYPOSITION | MF_POPUP, ITEM_MENU_SET_PLAY , TEXT("Set"));
::InsertMenu(Submenu , (-1), MF_BYPOSITION | MF_POPUP, ITEM_MENU_QUIT_PLAY , TEXT("Quit"));
}
}
WinPopMenu::~WinPopMenu()
{
if (m_pPopMenu)
{
DestroyMenu(m_pPopMenu);
m_pPopMenu = NULL;
}
}
void WinPopMenu::PopMenu(HWND hwnd, int nX, int nY)
{
if (m_pPopMenu && hwnd)
{
TrackPopupMenu(m_pPopMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, nX, nY, 0, hwnd, NULL);
}
}
void WinPopMenu::PopMenu(HWND hwnd, const POINT& pt)
{
PopMenu(hwnd, pt.x, pt.y);
}
};
void OnCreate(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
int scrWidth, scrHeight;
scrWidth = GetSystemMetrics(SM_CXSCREEN);
scrHeight = GetSystemMetrics(SM_CYSCREEN);
LONG styleValue = ::GetWindowLong(hwnd, GWL_STYLE);
::SetWindowLong(hwnd, GWL_STYLE, styleValue & (~WS_CAPTION));
DWORD dwExStyle = ::GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, dwExStyle & ~(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME));
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
}
LRESULT OnMenuEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId = LOWORD(wParam);
switch (wmId)
{
case ITEM_MENU_SCREEN_1:
{
MessageBox(NULL, TEXT("ITEM_MENU_SCREEN_1"), TEXT("ITEM_MENU_SCREEN_1"), MB_OK);
break;
}
case ITEM_MENU_SCREEN_2:
{
MessageBox(NULL, TEXT("ITEM_MENU_SCREEN_2"), TEXT("ITEM_MENU_SCREEN_2"), MB_OK);
break;
}
case ITEM_MENU_SCREEN_3:
{
MessageBox(NULL, TEXT("ITEM_MENU_SCREEN_3"), TEXT("ITEM_MENU_SCREEN_3"), MB_OK);
break;
}
case ITEM_MENU_SCREEN_4:
{
MessageBox(NULL, TEXT("ITEM_MENU_SCREEN_4"), TEXT("ITEM_MENU_SCREEN_4"), MB_OK);
break;
}
case ITEM_MENU_STOP_PLAY:
{
MessageBox(NULL, TEXT("ITEM_MENU_STOP_PLAY"), TEXT("ITEM_MENU_STOP_PLAY"), MB_OK);
break;
}
case ITEM_MENU_START_PLAY:
{
MessageBox(NULL, TEXT("ITEM_MENU_START_PLAY"), TEXT("ITEM_MENU_START_PLAY"), MB_OK);
break;
}
case ITEM_MENU_SET_PLAY:
{
MessageBox(NULL, TEXT("ITEM_MENU_SET_PLAY"), TEXT("ITEM_MENU_SET_PLAY"), MB_OK);
break;
}
case ITEM_MENU_QUIT_PLAY:
{
CloseWindow(hWnd);
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);;
break;
}
return 0;
}
void OnLRMouseDownUp(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_RBUTTONDOWN:
{
POINT pt;
::GetCursorPos(&pt);
WinPopMenu* pPopMenu = new WinPopMenu;
pPopMenu->PopMenu(hWnd, pt);
break;
}
break;
case WM_LBUTTONDOWN:
{
SetCapture(hWnd);
GetCursorPos(&pointDown);
GetWindowRect(hWnd, &clientRect);
clientRect.right = clientRect.right - clientRect.left;
clientRect.bottom = clientRect.bottom - clientRect.top;
break;
}
case WM_LBUTTONUP:
{
POINT pe;
GetCursorPos(&pe);
clientRect.left = clientRect.left + (pointUp.x - pointDown.x);
clientRect.top = clientRect.top + (pointUp.y - pointDown.y);
MoveWindow(hWnd, clientRect.left, clientRect.top, clientRect.right, clientRect.bottom, true);
ReleaseCapture();
break;
}
case WM_MOUSEMOVE:
{
GetCursorPos(&pointUp);
break;
}
}
}
void OnPaint(HWND hWnd, HDC hdc)
{
RECT client;
GetClientRect(hWnd, &client);
int Width = client.right - client.left;
int Height = client.bottom - client.top;
HDC memDC = CreateCompatibleDC(hdc);
HBITMAP memBitmap = CreateCompatibleBitmap(hdc, Width, Height);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
SetRect(&client, 0, 0, Width, Height);
HBRUSH hBrush = CreateSolidBrush(RGB(4, 109, 192));
FillRect(memDC, &client, hBrush);
BitBlt(hdc, 0, 0, Width, Height, memDC, 0, 0, SRCCOPY);
SelectObject(memDC, hOldBitmap);
DeleteObject(hBrush);
DeleteObject(memBitmap);
DeleteDC(memDC);
}
LRESULT CALLBACK ParentWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
OnCreate(hWnd, wParam, lParam);
break;
}
case WM_COMMAND:
{
OnMenuEvent(hWnd, message, wParam, lParam);
break;
}
case WM_RBUTTONDOWN:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
{
OnLRMouseDownUp(hWnd, message, wParam, lParam);
break;
}
case WM_PAINT:
{
HDC hdc = NULL;
PAINTSTRUCT ps;
if (hWnd == winHandle && !winLoadBk.load())
{
winLoadBk.store(true);
hdc = BeginPaint(hWnd, &ps);
OnPaint(hWnd, hdc);
EndPaint(hWnd, &ps);
}
else if (hWnd == subWinHandle && !subWinLoadBk.load())
{
subWinLoadBk.store(true);
hdc = BeginPaint(hWnd, &ps);
OnPaint(hWnd, hdc);
EndPaint(hWnd, &ps);
}
else
{
hdc = BeginPaint(hWnd, &ps);
OnPaint(hWnd, hdc);
EndPaint(hWnd, &ps);
}
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
LONG styleValue = ::GetWindowLong(hwnd, GWL_STYLE);
::SetWindowLong(hwnd, GWL_STYLE, styleValue & (~WS_CAPTION));
DWORD dwExStyle = ::GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, dwExStyle & ~(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME));
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
return 0;
}
case WM_LBUTTONDOWN:
{
return 0;
}
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hwnd, message, wParam, lParam);
}