728x90

출처 : http://tarotcrd.tistory.com/154

위의 출처에서 해당 글의 내용을 보고 참 도움을 많이 받기는 했는데, 가독성이 떨어지는데다, 해당 소스 부분을 직접 긁어 코드화 시킬 수 없어서 여기에 다시 정리해서 올린다.

Winform-WebBrowser Control을 이용하면, 웹의 내용을 그대로 띄울 수 있다.
그래서 WinForm과는 다른 유연하게 제공되는 표(Table)을 표현 할 수 있고, 각종 Form을 구성할 수도 있다.

그런데, 이런 웹 기반의 프로그램을 이런 저런 구성하다가 보면, 웹의 내용을 표출하는 것 뿐만 아니라, 웹에서 입력된 각종 값들을 WinForm에서 활용하고 싶을 때가 있다. 이 경우 Javascript를 통해 웹 상의 정보를 읽는 것은 가능한데, 이 정보를 WinForm에 어떻게 전달할까?

역으로, WinForm에서 특정 작업을 수행했는데, 이 정보를 WebBrowser Control을 통해 웹 상에 전달 하고 싶을 때는 어떻게 할까?

위의 질문에 대한 답을 아래에 제시할 수 있다.

Web(Javascript) –> WinForm(Webbrowser Control)

맨 먼저 할 작업은 웹에서 제공되는 정보를 winform에서 받아서 처리하는 방법이다.

웹에서 먼저 javascript를 구성하도록 한다.

<html>
<head>
	<title>Test Page</title>
	<script type="text/javascript">
		function submitToForm()
		{
			var textboxvalue = document.getElementById('text1').value;
			window.external.CallForm(textboxvalue);
		}
	</script>
</head>
<body>
	<form>
		<input type="text" id="text1" name="text1"></input>
		<input type="button" id="btn1" name="btn1" value="submit" onclick="submitToForm()"></input>
	</form>
</body>
</html>

HTML 소스 중, Javascript만 보면, 다음과 같은 코드가 있다.

window.external.CallForm(textboxvalue);

바로 window.external 부분이 핵심인데, window.external까지 쓰고, 그 뒤에 C# Winform 상에서 실행할 함수 명과, 값을 넘겨줄 때 사용할 파라미터를 건네면 된다.

이제 웹브라우저 컨트롤을 Windows Form에 넣고 다음과 같이 코드를 수정하도록 한다.

TestApp 라는 솔루션 내에 Form1이라는 Winform을 하나 생성한 뒤에, 디자이너 화면에서 webbrowser 컨트롤을 폼에다 넣으면 된다. 자동적으로 webBrowser1 이라는 변수가 생성이 된다.




자 이제 소스 부분을 열도록 한다. 그리고 using을 사용해서 다음 두개의 네임스페이스를 추가한다.

using System.Security.Permissions;
using System.Runtime.InteropServices;

Form1에서 Form Load 이벤트 핸들러를 생성한다. (Form1_Load 함수가 자동으로 생성된다.). 그리고 그 안에 다음과 같은 속성을 설정하도록 한다.

webBrowser1.ObjectForScripting = true;

이제 javascript에서 호출받을 함수를 만든다. 위의 Javascript에서 CallForm 이라고 만들었으므로, 여기서도 CallForm이라는 이름의 함수를 새로 만들어 추가하면 된다.외부에서 노출되어야 되기 때문에, 반드시 public으로 만들어야 하며, 파라미터가 있을 시에는 파라미터 갯수만큼 object로 변수를 만든다.

public void CallForm(object msg)
{
	string sMsg = (string)msg;
	{
		// 받은 msg 값을 가지고 처리하는 로직.
	}
}

사실 Javascript에서는 데이터 형(문자열, 숫자, 날짜 등등)에 관계 없이 무조건 쓸 수 있지만, C#에서는 그 형이 정해져야 한다. 그렇다고, Javascript에서 맞춰줄 수는 없다. 방법은 Javascript에서 파라미터를 받을 때, object로 받아, 그 값의 형에 따라 캐스팅을 하는 방법을 제시한다.

위의 수정 내용을 다 합친 코드는 아래와 같다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Security.Permissions;
using System.Runtime.InteropServices;

namespace TestApp
{
    [PermissionSet(SecurityAction.Demand, Name="FullTrust")]
    [ComVisible(true)]
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            webBrowser1.ObjectForScripting = true;
        }

        public void CallForm(object msg)
        {
            string sMsg = (string)msg;
            {
                // 받은 msg 값을 가지고 처리하는 로직.

            }
        }
    }

WinForm –> Web(Javascript)

이제 역으로 WinForm에서 webBrowser 컨트롤 내에 띄워진 Javascript를 실행하는 방법을 제시한다.
이 부분은 앞서 설명한 방법과는 다르게 webControl에게 시키기만 하면 된다.

먼저 Winform에서는 다음과 같은 코드를 작성한다.

private void ExecJavascript(string sValue1, string sValue2)
{
	try
	{
		webBrowser1.Document.InvokeScript("CallScript", new object[] { sValue1, sValue2 });
	}
	catch
	{
        }
}

보면 Javascript를 부를 때, Document.InvokeScript를 사용한다는 것을 쉽게 알 수 있다. 해당 함수의 첫번째 파라미터에는 호출 할 Javascript의 함수 이름을 넣고, 두 번째에는 object 배열로 해서 파라미터를 넘기면 된다. ( c#의 invoke를 사용해 본적이 많으면 쉽다.) 만일 파라미터가 여러 개인 경우에는 갯수에 맞게 개수를 늘려 배열로 생성해주면 된다.

자 이제 javascript 부분을 살펴보자. 다른 HTML 부분은 필요없고, script 섹션 내에 위의 설정한 “CallScript”라는 함수를 생성해주면 된다.

function CallScrript(va1, va2)
{
	alert('Val1 : ' + val1 + " / Val2 : ' + val2);
}

이제 WinForm에서 webbrowser1.Document.InvokeScript를 실행하면, webBrowser 컨트롤 내의 HTML Script가 실행 됩니다.

 

정리

Javascript –> WinForm을 호출하는 방식은 Javascript에서 ActiveX 를 호출하는 것과 비슷하다. 보안적인 이슈만 없다면, HtML 위에 작성된 javscript 호출하는 것 역시 간단하다.사실 webBrowser 컨트롤이 WinForm과 거의 한몸이기 때문에 이런 방식이 가능하다. 

스스로 예제를 작성해서 구성해 보면 좀 더 확실하게 이해 할 수 있을 것이다. 

728x90
  1. Favicon of https://tsblog.simulz.kr Simulz 2016.04.27 18:39 신고

    우와~ 끝내줍니다. 잘 되네요!
    PHP만 하다가 C# 연동하고 싶었는데

    배열이나 오브젝트 전달은 어떻게 하나요?

  2. 지나가다 2019.12.04 10:39

    스크립트 오류가 나는데,
    webBrowser1.ObjectForScripting = true; 가 아니라
    webBrowser1.ObjectForScripting = this; 라고 해야 합니다.

  3. zxcvsdfasd12 2021.05.08 04:37

    감사합니다!!

+ Recent posts