⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvdsynth.cpp

📁 DVD工具dvdsynth的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
 Copyright 2002 Ben Rudiak-Gould.

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA,
 or visit <http://www.gnu.org/copyleft/gpl.html>.
***********************************************************************/


#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
#include <commctrl.h>
#include <process.h>
#include <time.h>

#include "/p/lib/myvector.h"
#include "/p/lib/mystring.h"

#include "resource.h"
#include "../include/dvdsynth-plugin.h"


/*******************************************************************\
\*******************************************************************/


union Value {
   int i;
   unsigned u;
   const char* s;
};


static inline const char* FormatValue(Value v, char type) {
   if (type == 's') {
      return v.s;
   } else {
      switch (type) {
      case 'i': case 'd': case 'u': case 'X': case 'c':
         {
            static char buf[3*sizeof(int)];
            static char fmt_str[] = "%_";
            fmt_str[1] = type;
            wsprintf(buf, fmt_str, v.i);
            return buf;
         }
      default:
         return "???";
      }
   }
}


int Sprint(char* buf, int space, const char* fmt, const char* types, ...) {
   if (types == 0) {
      types = "sssssssss";
   }
   int num_types = lstrlen(types);

   const char* p = fmt;
   char* q = buf;
   char* q_end = buf + space - 1;
   for (;;) {
      if (*p == '%' && *(p+1) >= '1' && *(p+1) <= '9') {
         va_list val;
         va_start(val, types);
         Value value;
         int arg_number = *(p+1) - '0';
         char type;
         for (int i=0; i<arg_number; ++i) {
            type = types[i];
            if (type == 's') {
               value.s = va_arg(val, const char*);
            } else {
               value.i = va_arg(val, int);
            }
         }
         va_end(val);
         const char* insert = FormatValue(value, type);
         if (insert == 0) {
            insert = "(null)";
         }
         int insert_len = lstrlen(insert);
         memcpy(q, insert, min(insert_len, q_end - q));
         q += insert_len;
         p += 2;
      } else if (*p != 0) {
         if (q < q_end) {
            *q = *p;
         }
         ++q; ++p;
      } else {
         break;
      }
   }
   *min(q, q_end) = 0;
   return q - buf;
}


/*******************************************************************\
\*******************************************************************/


class PopupMenu : public DvsMenu {

   class Callback {
      void (*callback)(void*, int);
      void* p;
      int i;
   public:
      Callback(void (*_callback)(void*, int), void* _p, int _i) {
         callback = _callback; p = _p; i = _i;
      }
      void Invoke() {
         if (callback)
            callback(p,i);
      }
   };

   Vector<Callback> callbacks;
   Vector<HMENU> menu_stack;
   HMENU top_level_popup;
   int base_submenu_level;
   bool add_separator;
   bool menu_empty;

   void InternalAddItem(UINT flags, UINT id, LPCTSTR text);

public:

   PopupMenu() {
      static DvsMenu_vtable vt = {
         StaticAddSeparator,
         StaticAddItem,
         StaticAddDisabledItem,
         StaticBeginSubmenu,
         StaticEndSubmenu,
      };
      vtable = &vt;

      top_level_popup = CreatePopupMenu();
      menu_stack.push_back(top_level_popup);
      base_submenu_level = 1;
      add_separator = false;
      menu_empty = true;
   }

   HMENU GetPopup() {
      return top_level_popup;
   }

   void InvokeCallback(int index) {
      if (index > 0 && index <= callbacks.size()) {
         callbacks[index-1].Invoke();
      }
   }

   ~PopupMenu() {
      DestroyMenu(top_level_popup);
   }

   // The purpose of the lock/unlock stuff is to prevent buggy plugins
   // from screwing up the whole menu structure.
   void LockSubmenuLevel() {
      base_submenu_level = menu_stack.size();
   }
   void UnlockSubmenuLevel() {
      // assert(menu_stack.size() == base_submenu_level);
      while (menu_stack.size() > base_submenu_level) {
         EndSubmenu();
      }
      base_submenu_level = 1;
   }

   void AddSeparator() {
      add_separator = true;
   }
   void AddItem(const char* text, int checked, void (*callback)(void*, int), void* p, int i) {
      callbacks.push_back(Callback(callback, p, i));
      InternalAddItem(!!checked*MF_CHECKED, callbacks.size(), text);
   }
   void AddDisabledItem(const char* text, int checked) {
      InternalAddItem(MF_GRAYED + !!checked*MF_CHECKED, (UINT)-1, text);
   }
   void BeginSubmenu(const char* text, int disabled) {
      HMENU submenu = CreatePopupMenu();
      InternalAddItem(MF_POPUP + !!disabled*MF_GRAYED, (UINT)submenu, text);
      menu_stack.push_back(submenu);
      menu_empty = true;
   }
   void EndSubmenu() {
      // assert(menu_stack.size() > base_submenu_level);
      if (menu_stack.size() > base_submenu_level) {
         if (menu_empty) {
            InternalAddItem(MF_GRAYED, 0, "(empty)");
         }
         menu_stack.pop_back();
         add_separator = false;
         //menu_empty = false;
      }
   }

   static void StaticAddSeparator(DvsMenu* self) {
      reinterpret_cast<PopupMenu*>(self)->AddSeparator();
   }
   static void StaticAddItem(DvsMenu* self, const char* text, int checked, void (*callback)(void*, int), void* p, int i) {
      reinterpret_cast<PopupMenu*>(self)->AddItem(text, checked, callback, p, i);
   }
   static void StaticAddDisabledItem(DvsMenu* self, const char* text, int checked) {
      reinterpret_cast<PopupMenu*>(self)->AddDisabledItem(text, checked);
   }
   static void StaticBeginSubmenu(DvsMenu* self, const char* text, int disabled) {
      reinterpret_cast<PopupMenu*>(self)->BeginSubmenu(text, disabled);
   }
   static void StaticEndSubmenu(DvsMenu* self) {
      reinterpret_cast<PopupMenu*>(self)->EndSubmenu();
   }
};

void PopupMenu::InternalAddItem(UINT flags, UINT id, LPCTSTR text) {
   if (add_separator && !menu_empty) {
      AppendMenu(menu_stack.back(), MF_SEPARATOR, 0, 0);
   }
   AppendMenu(menu_stack.back(), flags, id, text);
   add_separator = false;
   menu_empty = false;
}


/*******************************************************************\
\*******************************************************************/


char g_dvdsynth_directory[MAX_PATH+1];

void ExtractDvdsynthDirectory(const char* exe_name) {
   char* filepart;
   if (GetFullPathName(exe_name, MAX_PATH, g_dvdsynth_directory, &filepart)) {
      if (filepart > g_dvdsynth_directory && (filepart[-1] == '\\' || filepart[-1] == '/')) {
         filepart[0] = 0;
      } else {
         filepart[0] = '\\';
         filepart[1] = 0;
      }
   } else {
      lstrcpy(g_dvdsynth_directory, ".\\");
   }
}

// returns 0 on failure, # bytes copied on success
const char* GetDvdsynthDirectory() {
   return g_dvdsynth_directory;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -