项目的创建和配置:

  1、新建一个 Win32 空项目

  2、创建源码文件夹、库文件夹和资源文件夹

  3、在 VS2013(我使用的 IDE 是 vs2013)配置这些文件夹

  这里使用了 $(SolutionDir) 宏来指定上面创建的文件夹,因为使用的不是绝对路径,所以将项目拷贝到其他文件夹或电脑也可以正确读取。通过上面的设置,告诉程序去哪找到源码文件和库文件。

  创建窗口:

  创建窗口有几个固定的步骤,只要按照这些步骤来就好了,下面是创建的代码

HWND Create()
{
/* 设计窗口类 */
WNDCLASS wndclass;
memset(&wndclass, , sizeof(WNDCLASSA)); wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wndclass.lpfnWndProc = ( WNDPROC ) WindowProc;
wndclass.cbClsExtra = ;
wndclass.cbWndExtra = ;
wndclass.hInstance = ( HINSTANCE ) GetModuleHandle();
wndclass.hIcon = ;
wndclass.hCursor = ;
wndclass.hbrBackground = CreateSolidBrush(RGB(, , ));
wndclass.lpszMenuName = ;
wndclass.lpszClassName = L"MMDViewer"; /* 注册窗口类 */
RegisterClass(&wndclass); /* 不能改变窗口大小 */
int style = WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX; /* 根据客户区大小计算窗口大小 */
RECT rect = { , , , };
AdjustWindowRect(&rect, style, ); /* 居中显示计算窗口位置和大小 */
int w = rect.right - rect.left;
int h = rect.bottom - rect.top;
int x = (GetSystemMetrics(SM_CXSCREEN) - w) / ;
int y = (GetSystemMetrics(SM_CYSCREEN) - h) / ; /* 创建窗口 */
HWND hwnd = CreateWindow(L"MMDViewer", L"MMDViewer", style, x, y, w, h, NULL, , ( HINSTANCE ) GetModuleHandle(), ); /* 显示窗口 */
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd); return hwnd;
}

  该函数返回新建的窗口句柄,需要注意的是,这里重新计算了窗口的大小。如果按 800x600 创建窗口,则窗口客户区的大小就会小于 800x600,因为客户区才是真正渲染的区域,所以希望客户区的大小就是 800x600,而窗口的大小需要重新计算。使用的函数是 AdjustWindowRect(),它能过返回窗口的需要大小。

  还有就是窗口事件处理函数,这里添加了可以使窗口关闭的代码:

LRESULT CALLBACK WindowProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch ( msg )
{
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage();
break;
case WM_PAINT:
RECT rect;
if ( GetUpdateRect(wnd, &rect, FALSE) )
{
ValidateRect(wnd, &rect);
}
break;
}
return DefWindowProc(wnd, msg, wParam, lParam);
}

  最后就是事件循环,它在主函数中:

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine); HWND hwnd = Create(); /* 主事件循环 */
MSG msg = { };
while ( WM_QUIT != msg.message )
{
if ( PeekMessage(&msg, NULL, , , PM_REMOVE) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return ( int ) msg.wParam;
}

  编译程序,成功运行后就会弹出一个窗口:

  源码下载:MMDViewer 02.zip

最新文章

  1. Rigidbody相关的操作最好放在FixedUpdate中,update中可能会无效果
  2. WIN32服务程序(二):卸载服务
  3. emgucv文字识别
  4. JVM性能优化入门指南
  5. 详解MySQL---DDL语句、DML语句与DCL语句
  6. java 数组基本操作(一维)
  7. VS2015中DataGridView的DataGridViewComBoboxCell列值无效及数据绑定错误的解决方法
  8. Oracle AWR报告指标全解析-11011552
  9. new SqlSessionFactoryBuilder().build(inputStream, properties)
  10. lvs_nat
  11. Android-满屏幕拖动的控件
  12. android sdutio常用快捷键
  13. GDB disassemble
  14. apk公钥私钥用法
  15. java通过jdbc访问mysql,update数据返回值的思考
  16. 软间隔分类——SVM
  17. Linux下DNS简单部署(主从域名服务器)
  18. [LeetCode] 586. Customer Placing the Largest Number of Orders_Easy tag;SQL
  19. Elasticsearch搜索异常-------org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper: parse_exception
  20. c# double 类型保留几位小数

热门文章

  1. Eclipse web工程 部署 三种方式 1
  2. GLSL 内建函数
  3. 每天一个linux命令(文件操作):【转载】locate命令
  4. WPF 跨应用程序域的 UI(Cross AppDomain UI)
  5. BestCoder Round #1 第一题 逃生
  6. WordCount运行详解
  7. bean:write
  8. Tree的两种存储形式
  9. 【最全 干货 实例】 缓存手册(Memcached、redis、RabbitMQ)
  10. hoverfly api 模拟框架了解