C++动态链接库DLL文件的内部窗口显示

1、功能描述

对话框可以分为modal和modeless两种。

2、在Win32 Dll中创建modal对话框

在一个Win32Dll中创建modal对话框非常简单,我们都知道,Win32函数DialogBox能够创建一个modal对话框,并且modal对话框的消息是独立于主程序消息循环的,所以可以直接在Dll内部建立对话框自己的窗口过程。下面就是一个在Win32 Dll中创建modal对话框的示例:

//name: Modal_Dialog.cpp
#include<windows.h>
#include"resource.h"
BOOL CALLBACK DlgProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 {
     switch( Msg )
     {
     case WM_INITDIALOG:
         return TRUE;
 
     case WM_COMMAND:
         switch( wParam )
         {
         case IDOK:
              MessageBox(NULL, "这是一个modal对话框的例子", "提示", MB_OK);       
              EndDialog(hwnd, 0);
              return TRUE;
         }
         break;
     }
 
     return FALSE;
 }
extern"C" __declspec(dllexport) void ShowDialog()
{
     HINSTANCE hinst;
     hinst=LoadLibrary("Modal_Dialog.dll");     //获取库所在的实例句柄
     DialogBox(hinst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
     FreeLibrary(hinst);
}
	 typedef void (*fp)();
     HINSTANCE hDll;
     fp Show;
     hDll = LoadLibrary("Modal_Dialog.dll");
     Show = (fp)GetProcAddress(hDll,"ShowDialog");
     (*Show)();
     FreeLibrary(hDll);

3、在Win32 Dll中创建modeless对话框

与modal对话框不同,modeless对话框的消息是要经过主程序消息循环的,这样一来,就必须在调用该Dll的主程序中处理对话框的消息循环,这就无法达到利用Dll来完成组件化开发的要求。其实我们可以人为的Modeless对话框创建一个窗口类,我们知道窗口过程是属于窗口类的,这样一来就有了主窗口的消息循环。


//name: Modeless_Dialog.cpp
#include <windows.h>
#include"resource.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
 
extern"C" int __declspec(dllexport) ShowDialog()
{
     static TCHAR szAppName[] = TEXT("Modeless_Dialog");
     HWND hwnd;
     MSG msg;
     WNDCLASS wndclass;
     HINSTANCE hInstance;
     HWND hDialog;
 
     hInstance = LoadLibrary("Modeless_Dialog.dll");
    
     wndclass.style         = CS_HREDRAW | CS_VREDRAW;
     wndclass.lpfnWndProc   = WndProc;
     wndclass.cbClsExtra    = 0;
     wndclass.cbWndExtra    = DLGWINDOWEXTRA;    // Note!
     wndclass.hInstance     = hInstance;
     wndclass.hIcon         = LoadIcon(hInstance, szAppName);
     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
     wndclass.lpszMenuName  = NULL;
     wndclass.lpszClassName = szAppName;
     hwnd = CreateWindow(szAppName, TEXT("Modeless_Dialog"),
                          WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL);
    
     // ShowWindow (hwnd, iCmdShow); //并不在这里显示主窗口
     // UpdateWindow (hwnd);  
     hDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, DlgProc) ;
    
     while ( GetMessage(&msg, NULL, 0, 0) )
     {
          if( hDialog == 0 || !IsDialogMessage(hDialog, &msg) )
          {
               TranslateMessage(&msg);
               DispatchMessage(&msg);
          }
     }
     return msg.wParam ;
 
}
BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
     switch( message )
     {
     case WM_INITDIALOG:
          return true;
     case WM_COMMAND:
          switch( wParam )
          {
          case(IDOK):
               MessageBox(NULL, "这是一个modeless对话框的例子", "提示", MB_OK);
               DestroyWindow(hDlg);
               PostQuitMessage(0);
               return TRUE;
          }
     }
     return FALSE;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{   
     switch ( message )
     { 
     case WM_DESTROY:
          PostQuitMessage(0);
          return 0;
     }
     return DefWindowProc(hwnd, message, wParam, lParam);
}

3、C/C++控制台程序隐藏窗口

  • 方法1
    在代码头文件下加上一句:
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) // 设置入口地址
#include<windows.h>
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) // 设置入口地址
int main()
{
	MessageBox(NULL,"Hello","爱看书的小沐",NULL);
	return 0;
}

注意:在编译器下运行时仍会出现黑框,但直接运行编译好的exe程序就不会显示黑框了。

  • 方法2:
    使用API函数隐藏自身窗口,但会有黑框快速闪过。
#include<windows.h>
int main()
{
	HWND hwnd = NULL;
	hwnd=FindWindow("ConsoleWindowClass",NULL);	
	if(hwnd){
		ShowWindow(hwnd,SW_HIDE);
	}
	MessageBox(NULL,"Hello","爱看书的小沐",MB_OK);
	system("pause");
	return 0;
}
  • 方法3:
    写第二个程序,间接启动第一个程序,以窗口隐藏的方式。
#include<windows.h>
int main()
{
	WinExec("MyTest.exe", SW_HIDE);	
	return 0;
}
  • 方法4:
    编写vbscript脚本:object.Run(strCommand, [intWindowStyle], [bWaitOnReturn])
Set objShell = CreateObject(“Wscript.Shell) 
objShell.Run("MyTest.exe", 0, FALSE)  
Set objShell = CreateObject(“Wscript.Shell) 
objShell.Run “notepad” ,,true 
objShell.Run “calc” 
set wshshell = wscript.createobject("wscript.shell")
return = wshshell.run("notepad " & wscript.scriptfullname, 1, true)

run函数有三个参数:
第一个参数是你要执行的程序的路径。
第二个程序是窗口的形式,0是在后台运行;1表示正常运行;2表示激活程序并且显示为最小化;3表示激活程序并且显示为最大化;一共有10个这样的参数我只列出了4个最常用的。
第三个参数是表示这个脚本是等待还是继续执行,如果设为了true,脚本就会等待调用的程序退出后再向后执行。

其实,run做为函数,前面还有一个接受返回值的变量,一般来说如果返回为0,表示成功执行,如果不为0,则这个返回值就是错误代码,可以通过这个代码找出相应的错误。

后记

如果你觉得这些文字有一点点用处,可以给作者点个赞;╮( ̄▽ ̄)╭
如果你感觉作者写的不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进。o_O???
谢谢各位小伙伴们啦( ´ ▽ ‘)ノ ( ´ ▽ ` )っ!!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值