📄 mme.c
字号:
/*******************************************************************
MARUMO MPEG-2 EDITOR
*******************************************************************/
#include <limits.h>
#include <stdio.h>
#include <windows.h>
#include <commctrl.h>
#include <shellapi.h>
#include "resource.h"
#include "m2v_vfapi.h"
#include "mme_project.h"
#include "callback.h"
#include "query_frame.h"
#include "message.h"
#define MAIN_WINDOW_WIDTH 328
#define MAIN_WINDOW_HEIGHT 286
/*******************************************************************
type definition
*******************************************************************/
typedef struct {
HINSTANCE instance;
HWND main_hwnd;
HWND callback_dlg;
HWND slide_bar;
HACCEL accel_tbl;
M2V_VFAPI vfapi;
MME_PROJECT project;
HANDLE clipboard;
int lang;
char openpath[1024];
char savepath[1024];
} MME_APP;
#define MME_LANG_JA 0
#define MME_LANG_EN 1
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
/*******************************************************************
menu command procedures
*******************************************************************/
static void on_file_open();
static void on_file_close();
static void on_file_output();
static void on_file_benchmark();
static void on_file_goplist();
static void on_file_end();
static void on_edit_in();
static void on_edit_out();
static void on_edit_undo();
static void on_edit_copy();
static void on_move_frame();
static void on_move_timecode();
static void on_move_forward();
static void on_move_back();
static void on_move_next_i();
static void on_move_prev_i();
static void on_move_in();
static void on_move_out();
static void on_move_start();
static void on_move_end();
static void on_help_about();
/*******************************************************************
other windows message procedure
*******************************************************************/
static void on_destory();
static void on_paint();
static void on_cbdialog_cancel();
static void on_h_scroll(int code, HWND hwnd);
static void on_dropfiles(HANDLE hdrop);
/*------------------------------------------------------------------
file local functions
------------------------------------------------------------------*/
static void enable_menu_from_list(const UINT *list, int count);
static void disable_menu_from_list(const UINT *list, int count);
static void showdib(HDC hdc, const BITMAPINFOHEADER *header, const VOID *data);
static void resize(int client_width, int client_height);
static void update_slider();
static HRESULT _stdcall callback(char *path, DWORD percent);
static void msg_pump();
static void show_error(char *msg, DWORD code);
static void repaint();
static void open_file(char *path);
static void parse_cmdline(char *arg);
static void get_lastpath();
static void put_openpath(char *path);
static void put_savepath(char *path);
static void cut_filename(char *path);
static int has_suffix(char *path);
static DWORD get_goplist_mode();
static void put_goplist_mode(DWORD gl);
static void create_goplist(M2V_VFAPI *vfapi, char *path);
/*******************************************************************
global val
*******************************************************************/
WNDCLASS main_window = {
CS_HREDRAW | CS_VREDRAW,
WndProc,
0,
0,
0,
NULL,
NULL,
NULL,
NULL,
"MME_MAIN_WINDOW",
};
MME_APP mme_app;
/*******************************************************************
constants
*******************************************************************/
const char APP_NAME[] = "MME ver. 0.1.19";
const UINT SWITCHING_MENU_ID[] = {
ID_FILE_CLOSE,
ID_FILE_OUTPUT,
ID_FILE_BENCHMARK,
ID_EDIT_IN,
ID_EDIT_OUT,
ID_EDIT_COPY,
ID_MOVE_FRAME,
ID_MOVE_TIMECODE,
ID_MOVE_FORWARD,
ID_MOVE_BACK,
ID_MOVE_NEXT_I,
ID_MOVE_PREVIOUS_I,
ID_MOVE_IN,
ID_MOVE_OUT,
ID_MOVE_START,
ID_MOVE_END,
};
/*-----------------------------------------------------------------*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
RECT rect;
int width;
int height;
memset(&mme_app, 0, sizeof(MME_APP));
if(GetUserDefaultLangID() == 0x0411){
mme_app.lang = MME_LANG_JA;
main_window.lpszMenuName = "MME_MAIN_MENU_JA";
}else{
mme_app.lang = MME_LANG_EN;
main_window.lpszMenuName = "MME_MAIN_MENU_EN";
}
if(!open_m2v_vfapi(&(mme_app.vfapi))){
MessageBox(0, "failed to find \"m2v.vfp\" VFAPI Plugin", "ERROR", MB_OK|MB_ICONERROR);
exit(EXIT_FAILURE);
}
if (!hPreInst) {
main_window.hInstance =hInstance;
main_window.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
main_window.hCursor =LoadCursor(NULL, IDC_ARROW);
main_window.hbrBackground =GetStockObject(WHITE_BRUSH);
if (!RegisterClass(&main_window)){
return FALSE;
}
}
mme_app.instance = hInstance;
mme_app.accel_tbl = LoadAccelerators(hInstance, "MME_MAIN_ACCELERATOR");
InitCommonControls();
mme_app.main_hwnd = CreateWindow(main_window.lpszClassName, APP_NAME, WS_OVERLAPPED|WS_MINIMIZEBOX|WS_SYSMENU|WS_CAPTION, CW_USEDEFAULT, CW_USEDEFAULT, MAIN_WINDOW_WIDTH, MAIN_WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
GetClientRect(mme_app.main_hwnd, &rect);
width = rect.right-rect.left;
height = rect.bottom-rect.top;
mme_app.slide_bar = CreateWindowEx(0, TRACKBAR_CLASS, "MME_SLIDE_BAR", WS_CHILD|WS_VISIBLE|TBS_NOTICKS|TBS_ENABLESELRANGE, 0, height-24, width, 24, mme_app.main_hwnd, (HMENU)IDC_SLIDE_BAR, mme_app.instance, NULL);
SendMessage(mme_app.slide_bar, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG(0, 100));
SendMessage(mme_app.slide_bar, TBM_SETSEL, (WPARAM) TRUE, (LPARAM) MAKELONG(0, 100));
EnableWindow(mme_app.slide_bar, FALSE);
ShowWindow(mme_app.main_hwnd, nCmdShow);
UpdateWindow(mme_app.main_hwnd);
DragAcceptFiles(mme_app.main_hwnd, TRUE);
parse_cmdline(lpszCmdLine);
get_lastpath();
while (GetMessage(&msg, NULL, 0, 0)) {
if(!TranslateAccelerator(mme_app.main_hwnd, mme_app.accel_tbl, &msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
/*-----------------------------------------------------------------*/
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_COMMAND:
switch (LOWORD(wParam)) {
case ID_FILE_OPEN:
on_file_open();
break;
case ID_FILE_CLOSE:
on_file_close();
break;
case ID_FILE_OUTPUT:
on_file_output();
break;
case ID_FILE_BENCHMARK:
on_file_benchmark();
break;
case ID_FILE_GOPLIST:
on_file_goplist();
break;
case ID_FILE_END:
on_file_end();
break;
case ID_EDIT_IN:
on_edit_in();
break;
case ID_EDIT_OUT:
on_edit_out();
break;
case ID_EDIT_UNDO:
on_edit_undo();
break;
case ID_EDIT_COPY:
on_edit_copy();
break;
case ID_MOVE_FRAME:
on_move_frame();
break;
case ID_MOVE_TIMECODE:
on_move_timecode();
break;
case ID_MOVE_FORWARD:
on_move_forward();
break;
case ID_MOVE_BACK:
on_move_back();
break;
case ID_MOVE_NEXT_I:
on_move_next_i();
break;
case ID_MOVE_PREVIOUS_I:
on_move_prev_i();
break;
case ID_MOVE_IN:
on_move_in();
break;
case ID_MOVE_OUT:
on_move_out();
break;
case ID_MOVE_START:
on_move_start();
break;
case ID_MOVE_END:
on_move_end();
break;
case ID_HELP_ABOUT:
on_help_about();
break;
}
break;
case WM_DESTROY:
on_destory();
break;
case WM_PAINT:
on_paint();
return (1L);
case WM_CBDIALOG_CANCEL:
on_cbdialog_cancel();
break;
case WM_HSCROLL:
on_h_scroll(LOWORD(wParam), (HWND)lParam);
break;
case WM_DROPFILES:
on_dropfiles((HANDLE)wParam);
break;
default:
return(DefWindowProc(hWnd, msg, wParam, lParam));
}
return (0L);
}
/*-----------------------------------------------------------------*/
static void on_file_open()
{
OPENFILENAME of;
char path[1024];
/* initialize */
memset(&of, 0, sizeof(OPENFILENAME));
memset(path, 0, sizeof(path));
of.lStructSize = sizeof(OPENFILENAME);
of.hwndOwner = mme_app.main_hwnd;
of.lpstrFile = path;
of.nMaxFile = sizeof(path);
of.lpstrFilter = mme_app.vfapi.info.cFileType;
of.nFilterIndex = 0;
of.lpstrFileTitle = NULL;
of.nMaxFileTitle = 0;
of.lpstrInitialDir = mme_app.openpath;
of.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
if(GetOpenFileName(&of)){
put_openpath(of.lpstrFile);
open_file(of.lpstrFile);
}
return;
}
/*-----------------------------------------------------------------*/
static void on_file_close()
{
if(is_open_mme_project(&(mme_app.project))){
close_mme_project(&(mme_app.project));
disable_menu_from_list(SWITCHING_MENU_ID, sizeof(SWITCHING_MENU_ID)/sizeof(UINT));
InvalidateRgn(mme_app.main_hwnd, NULL, TRUE); /* repaint */
SetWindowText(mme_app.main_hwnd, APP_NAME);
SendMessage(mme_app.slide_bar, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG(0, 100));
SendMessage(mme_app.slide_bar, TBM_SETSEL, (WPARAM) TRUE, (LPARAM) MAKELONG(0, 100));
EnableWindow(mme_app.slide_bar, FALSE);
}
return;
}
/*-----------------------------------------------------------------*/
static void on_file_output()
{
OPENFILENAME of;
char path[260];
/* initialize */
memset(&of, 0, sizeof(OPENFILENAME));
memset(path, 0, sizeof(path));
of.lStructSize = sizeof(OPENFILENAME);
of.hwndOwner = mme_app.main_hwnd;
of.lpstrFile = path;
of.nMaxFile = sizeof(path);
of.lpstrFilter = mme_app.vfapi.info.cFileType;
of.nFilterIndex = 0;
of.lpstrFileTitle = NULL;
of.nMaxFileTitle = 0;
of.lpstrInitialDir = mme_app.savepath;
of.Flags = OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
if(GetSaveFileName(&of)){
if(!has_suffix(of.lpstrFile)){
strcat(of.lpstrFile, ".mpg");
}
put_savepath(of.lpstrFile);
mme_app.callback_dlg = open_callback_dialog(mme_app.instance, mme_app.main_hwnd, mme_app.lang);
SetActiveWindow(mme_app.callback_dlg);
ShowWindow(mme_app.main_hwnd, FALSE);
if(! output_mme_project(&(mme_app.project), path, callback)){
MessageBox(mme_app.main_hwnd, get_error_msg_mme_project(&(mme_app.project)), "INFO", MB_OK|MB_ICONINFORMATION);
}
DestroyWindow(mme_app.callback_dlg);
mme_app.callback_dlg = (HWND)INVALID_HANDLE_VALUE;
ShowWindow(mme_app.main_hwnd, TRUE);
}
return;
}
/*-----------------------------------------------------------------*/
static void on_file_benchmark()
{
__int64 i;
int msec;
int start;
__int64 fps;
char buffer[1024];
EnableWindow(mme_app.main_hwnd, FALSE);
start = GetTickCount();
for(i=mme_app.project.in_point;i<mme_app.project.out_point+1;i++){
set_frame_index_mme_project(&(mme_app.project), i);
update_slider();
SetWindowText(mme_app.main_hwnd, get_status_str_mme_project(&(mme_app.project)));
InvalidateRgn(mme_app.main_hwnd, NULL, FALSE); /* repaint */
msg_pump();
}
i = mme_app.project.out_point - mme_app.project.in_point;
msec = GetTickCount() - start;
fps = i * 1000 * 1000 / msec;
sprintf(buffer, "frame %I64d, time %d msec, fps %d.%03d", i, msec, (int)fps/1000, (int)fps%1000);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -