【转】win32 的DLL中创建windows窗口

转自:https://blog.51cto.com/wangyw/1071967

       因工作需求,需要写一个DLL,并在其中创建windows窗口,网上有很多关于DLL创建窗口的文章,不过都是基于MFC的, 却鲜见直接用win32的DLL创建的。经过研究调试,实现了在win32 DLL中创建窗口,总结成文,分享一下。

用win32 DLL创建窗口有一个问题:

CreateWindow用到的HINSTANCE从哪里来?

答:使用DllMain中的hModule

      BOOL APIENTRY DllMain(HANDLE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)

      hModule虽然是HANDLE,不能直接使用,但是经过强转即可直接使用:

      g_hIntance= (HINSTANCE)hModule;

      Handle 是代表系统的内核对象,如文件句柄,线程句柄,进程句柄。

      HMODULE 是代表应用程序载入的模块,win32系统下通常是被载入模块的线性地址

      HINSTANCE 在win32下与HMODULE是相同的东西,在Win32下还存在主要是因为win16。

      这是来自百度百科的解释【1】。

      显然HINSTANCE和HANDLE是两个玩意,但这里却可以强转,并成功了。调试过程中,看到的值

      hModule 是0x10000000

      g_hIntance是0x10000000,成员unused的值是9460301,

      显然,hModule和g_hInstance 是模块的起始地址。

      LoadLibrary返回的HINSTANCE值也是模块的起始地址,于是可以直接使用。

      难道2者有什么关联?不细说了,有空研究。

 

    实际运行中,我是将win32 windows的模板代码直接拷过来,直接把WinMain作为一个函数给DLL调用了,但不完善,遇到以下问题:

    1. 编译错误。一些宏没有了。

解决:需要将resource.h、资源文件和一些资源如ico拷过来。

    2. 窗口显示不了。

原因:跟了一下ShowWindow,发现返回值是0,表示窗口隐藏,原来是由nCmdShow决定的,由于没有值,就全部给了NULL或0。

解决:给nCmdShow改成1之后就OK了。

    贴一下代码:

    //dllmain

    // ad.cpp : 定义 DLL 应用程序的入口点。

#include "stdafx.h"
#include "ad.h"
#include "winform.h"
#include <process.h>

HINSTANCE g_hIntance;

int flag=0;

void c(void *)
{
flag=1;
MyCreateWindow(g_hIntance,NULL,NULL,1);
return;
}

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved)

{
g_hIntance= (HINSTANCE)hModule;
if(flag==0){
_beginthread(c,NULL,NULL);
flag=1;
}

switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
    return TRUE;
}

// 这是导出变量的一个示例

AD_API int nad=0;

 

// 这是导出函数的一个示例。
AD_API int fnad(void)
{
return 42;
}

// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 ad.h
Cad::Cad()

return; 
}

 

//winform.h

// ad.cpp : 定义应用程序的入口点。

#include "stdafx.h"
#include "resource.h"
#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名

BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()

 

// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY MyCreateWindow(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
  // TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;

// 初始化全局字符串
//LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
//LoadString(hInstance, IDC_AD, szWindowClass, MAX_LOADSTRING);

ATOM r=MyRegisterClass(hInstance);

 

// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow)) 
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_AD);

//  主消息循环:
while (GetMessage(&msg, NULL, 0, 0)) 
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return 0;
}

 

 

 

//

//  函数: MyRegisterClass()

//

//  目的: 注册窗口类。

//

//  注释: 

//

//    仅当希望在已添加到 Windows 95 的

//    “RegisterClassEx”函数之前此代码与 Win32 系统兼容时,

//    才需要此函数及其用法。调用此函数

//    十分重要,这样应用程序就可以获得关联的

//   “格式正确的”小图标。

//

ATOM MyRegisterClass(HINSTANCE hInstance)

{

WNDCLASSEX wcex;

 

wcex.cbSize = sizeof(WNDCLASSEX); 

 

wcex.style = CS_HREDRAW | CS_VREDRAW;

wcex.lpfnWndProc = (WNDPROC)WndProc;

wcex.cbClsExtra = 0;

wcex.cbWndExtra = 0;

wcex.hInstance = hInstance;

wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_AD);

wcex.hCursor = LoadCursor(NULL, IDC_ARROW);

wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

wcex.lpszMenuName = (LPCTSTR)IDC_AD;

wcex.lpszClassName = _T("TEST");

wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

 

return RegisterClassEx(&wcex);

}

 

//

//   函数: InitInstance(HANDLE, int)

//

//   目的: 保存实例句柄并创建主窗口

//

//   注释: 

//

//        在此函数中,我们在全局变量中保存实例句柄并

//        创建和显示主程序窗口。

//

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

   HWND hWnd;

 

   hInst = hInstance; // 将实例句柄存储在全局变量中

 

   hWnd = CreateWindow(_T("TEST"), _T("TEST"), WS_OVERLAPPEDWINDOW,

      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

 

   if (!hWnd)

   {

  DWORD r=GetLastError();

           return FALSE;

   }

 

   BOOL r1=ShowWindow(hWnd, nCmdShow);

   //DWORD r=GetLastError();

   r1=UpdateWindow(hWnd);

   //r=GetLastError();

 

   return TRUE;

}

 

//

//  函数: WndProc(HWND, unsigned, WORD, LONG)

//

//  目的: 处理主窗口的消息。

//

//  WM_COMMAND - 处理应用程序菜单

//  WM_PAINT - 绘制主窗口

//  WM_DESTROY - 发送退出消息并返回

//

//

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

int wmId, wmEvent;

PAINTSTRUCT ps;

HDC hdc;

 

//*********************

 

//**********************

switch (message) 

{

case WM_COMMAND:

wmId    = LOWORD(wParam); 

wmEvent = HIWORD(wParam); 

// 分析菜单选择:

switch (wmId)

{

case IDM_ABOUT:

DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);

break;

case IDM_EXIT:

DestroyWindow(hWnd);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

break;

case WM_PAINT:

hdc = BeginPaint(hWnd, &ps);

// TODO: 在此添加任意绘图代码...

EndPaint(hWnd, &ps);

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}

 

// “关于”框的消息处理程序。

LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

switch (message)

{

case WM_INITDIALOG:

return TRUE;

 

case WM_COMMAND:

if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 

{

EndDialog(hDlg, LOWORD(wParam));

return TRUE;

}

break;

}

return FALSE;

}

 

参考文献:

1.HINSTANCE  http://baike.baidu.com/view/2434154.htm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436158.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php 版权信息自动变化,php自动更新版权信息显示的方法

本文实例讲述了php自动更新版权信息显示的方法。。具体分析如下&#xff1a;我们一般会在页面下方输出版权信息&#xff0c;包含年份信息&#xff0c;每年都要修改&#xff0c;这段简单的代码帮你解决这个问题&#xff0c;自动更新年份function autoUpdatingCopyright($startYe…

【转】 ADO.NET最佳实践

本文转自&#xff1a;http://blog.csdn.net/spidertan/archive/2003/12/13/17110.aspx 概述&#xff1a; 本文在微软站点资源的基础上加工整理而成&#xff0c;意在介绍在你的ADO.NET应用程序中执行和完成性能优化、稳定性和功能性方面提供最佳的解决方案&#xff1b;同…

【转】Win32 Slider Control的用法

2.1 获得控件的窗口句柄。 slider control也是一个窗口&#xff0c;是对话框的子窗口&#xff0c;因此&#xff0c;要用GetDlgItem来实现&#xff1a; backlight_wnd GetDlgItem(hDlg, IDC_SLIDER_BACKLIGHT); //注意下面示例中蓝色标出的区别 2.2 设置slider control的区…

wince编译

在WinCE下面&#xff0c;创建工程&#xff0c;然后编译是需要花很长时间的。当我们第一编译完工程以后&#xff0c;如果需要改我们的驱动或者BSP&#xff0c;我们是不需要重新编译整个工程的&#xff1a;1. 如果更改了driver&#xff0c;以WinCE6.0为例&#xff0c;我们可以在菜…

php 变量文件间传递,同一文件的两个JS函数之间如何传变量?

满意答案ed_ch2013.11.06采纳率&#xff1a;44% 等级&#xff1a;12已帮助&#xff1a;8801人定义成全局变量就可以了var style_key;function change_mystyle(my){style_keymy.options[my.selectedIndex].value;if(style_key 114la){document.getElementById(shoostyleicon…

获取 Web 设计的免费资源

Web 开发人员可以找到很多免费资源&#xff0c;尽管其中一些资源会比另外一些资源更加自由。如果您正在设计网站或 Web 应用程序&#xff0c;那么不管是静态的还是所有可以想到的动态 Ajax 内容&#xff0c;都能找到减轻您的劳动强度并为网站增色的资源。本文从免费图标到 Web …

设计模式C++实现(1)——工厂模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

【转】关于CreateWindow的HINSTANCE参数?

学习Windows程序设计时&#xff0c;看见CreateWindows中有参数HINSTANCE&#xff0c;但不知道其用途&#xff0c;于是上网搜得两资料&#xff0c;并且&#xff0c;得出结果是&#xff0c;用于区分不同的应用实例。 What is the HINSTANCE passed to CreateWindow and RegisterC…

java对象间的转型,详细讲述Java中的对象转型

向上转型&#xff1a;子类对象转为父类&#xff0c;父类可以是接口。公式&#xff1a;Father f new Son();Father是父类或接口&#xff0c;son是子类。向下转型&#xff1a;父类对象转为子类。公式&#xff1a;Son s (Son)f;我们将形参设为父类Animal类型&#xff0c;当执行t…

给C盘减减肥,让你电脑飞一般速度!

当你买了台新电脑时&#xff0c;觉得性能&#xff0c;速度&#xff0c;你都比较满意&#xff0c;但是随着时间推移&#xff0c;你觉得你C盘空间越来越小&#xff0c;速度也降下了&#xff0c;那我们该怎么办呢&#xff1f;对于菜鸟来说&#xff0c;有一点你必须注意&#xff1a…

C++设计模式之一 工厂模式(简单工厂、工厂和抽象工厂)

今天开始这个系列之前&#xff0c;心里有些恐慌&#xff0c;毕竟园子里的高手关于设计模式的经典文章很多很多&#xff0c;特别是大侠李会军、吕震宇 老师的文章更是堪称经典。他们的文笔如行云流水&#xff0c;例子活泼生动&#xff0c;讲解深入浅出。好在他们都是用C#描述&am…

【转】Windows消息传递机制详解

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka Windows是一个消息&#xff08;Message&#xff09;驱动系统。Windows的消息提供了应用程序之间、应用程序与Windows系统之间进行通信的手段。应用程序想要实现的功能由消息来触发&#xff0c;并且靠对消…

matlab中邮递员问题实例,中国邮递员问题matlab

中国邮递员问题的EXCEL求... 1页 免费 对中国邮递员问题的数理... 4页 1下载券 中国邮递员问题matlab 6页 1下载券 喜欢...中国邮递员问题摘要:欧拉图起源于哥尼斯堡七桥问题,通过图中所有边一次且仅一次行遍...中国邮递员问题 (Chinese Postman Problem) 主要内容 七桥问题与一…

Response.Redirect(),Server.Transfer(),Server.Execute()的区别

Response.Redirect(),Server.Transfer(),Server.Execute()的区别 1、Response.Redirect(): Response.Redirect方法导致浏览器链接到一个指定的URL。当Response.Redirect()方法被调用时&#xff0c;它会创建一个应答&#xff0c;应答头中指出了状态代 码302&#xff08;表示目…

设计模式C++实现(2)——单例模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

php聊天室技术,PHP聊天室技术

PHP聊天室技术推荐查看本文HTML版本1&#xff0e;前言上网聊天是时下最流行的交友方式。各大网站推出的聊天室都各具特色。聊天室主要分为WebChat、BBSChat两种。BBSChat是基于Telnet的Tcp协议&#xff0c;是BBS的附设功能&#xff0c;需要客户端Telnet程序。WebChat则采用…

【转】深入理解Windows消息机制

转自&#xff1a;https://blog.csdn.net/liulianglin/article/details/14449577 今天我们来学一学Windows消息机制&#xff0c;我们知道在传统的C语音程序中&#xff0c;当我们需要打开一个文件时&#xff0c;我们可以调用fopen()函数&#xff0c;这个函数最后又会调用操作系统…

System.Drawing.Color.FromArgb(144,238,255);

if(dg.Items[i].Cells[iRow].Text "没完成") { dg.Items[i].BackColorSystem.Drawing.Color.FromArgb(144,238,255); } if(dg.Items[i].Cells[iRow].Text "已完成") { dg.Items[i].BackColorSystem.Drawing.Color.LightGreen;…

设计模式C++实现(3)——建造者模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

php tp 模板assign,thinkphp中怎么让assign在另一个模板里使用呢?

比如现在我有a.html和名字为b的控制器,现在我在b控制器里assing(‘b’,$b),那么请问在a.html中怎么调用b控制器中的assign呢?回复讨论(解决方案)代码是这样的Controller:public function a(){$this->display();}public function b(){if(IS_AJAX){$imageD(‘Image’);$b$ima…