728x90

1.웹뷰2의 환경 설정 및 기본 샘플 빌드 방법

 

Get started with WebView2 in Win32 apps - Microsoft Edge Developer documentation

Get started building WebView2 for Win32 by working with sample apps and the WebView2 SDK.

learn.microsoft.com

 

2.위 샘플에서 WebView2에 대한 소스 코드

// <-- WebView2 sample code starts here -->
// Step 3 - Create a single WebView within the parent window
// Locate the browser and set up the environment for WebView
CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
    Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
        [hWnd](HRESULT result, ICoreWebView2Environment* env) -> HRESULT 
        {
            // Create a CoreWebView2Controller and 
            // get the associated CoreWebView2 whose parent is the main window hWnd
            env->CreateCoreWebView2Controller(
                hWnd, 
                Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
                [hWnd](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT 
                {
                    if (controller != nullptr) 
                    {
                        webviewController = controller;
                        webviewController->get_CoreWebView2(&webview);
                    }
                    
                    // Add a few settings for the webview
                    // The demo step is redundant since the values are the default settings
                    wil::com_ptr<ICoreWebView2Settings> settings;
                    webview->get_Settings(&settings);
                    settings->put_IsScriptEnabled(TRUE);
                    settings->put_AreDefaultScriptDialogsEnabled(TRUE);
                    settings->put_IsWebMessageEnabled(TRUE);
                    
                    // Resize WebView to fit the bounds of the parent window
                    RECT bounds;
                    GetClientRect(hWnd, &bounds);
                    webviewController->put_Bounds(bounds);

                    // Schedule an async task to navigate to Bing
                    webview->Navigate(L"https://www.bing.com/");

                    return S_OK;
                }).Get());
            return S_OK;
        }).Get());

 

WebView2의 코드는 Callback 기반으로 동작한다.

 

// Step 4 - Navigation events
// register an ICoreWebView2NavigationStartingEventHandler to cancel any non-https navigation
EventRegistrationToken token;
webview->add_NavigationStarting(Callback<ICoreWebView2NavigationStartingEventHandler>(
    [](ICoreWebView2* webview, ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT 
    {
        wil::unique_cotaskmem_string uri;
        args->get_Uri(&uri);
        std::wstring source(uri.get());
        if (source.substr(0, 5) != L"https") 
        {
            args->put_Cancel(true);
        }
        return S_OK;
    }).Get(), &token);
  • Navigate할 때 이벤트를 등록할 수 있다
  • 위에 코드는 Navigation을 시작할 때 uri가 https 가 아니면 사이트를 열지 않겠다는 이벤트를 등록한다

 

// Step 5 - Scripting
// Schedule an async task to add initialization script that freezes the Object object
webview->AddScriptToExecuteOnDocumentCreated(L"Object.freeze(Object);", nullptr);
// Schedule an async task to get the document URL
webview->ExecuteScript(L"window.document.URL;", Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
    [](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT 
    {
        LPCWSTR URL = resultObjectAsJson;
        //doSomethingWithURL(URL);
        return S_OK;
    }).Get());
  • WebView2 컨트롤에 JavaScript 코드를 삽입할 수 있다
  • 삽입된 JavaScript는 JavaScript가 제거될 때까지 모든 새로운 최상위 문서와 모든 하위 프레임에 적용된다

 

// Step 6 - Communication between host and web content
// Set an event handler for the host to return received message back to the web content
webview->add_WebMessageReceived(Callback<ICoreWebView2WebMessageReceivedEventHandler>(
    [](ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT 
    {
        wil::unique_cotaskmem_string message;
        args->TryGetWebMessageAsString(&message);
        // processMessage(&message);
        webview->PostWebMessageAsString(message.get());
        return S_OK;
    }).Get(), &token);

// Schedule an async task to add initialization script that
// 1) Add an listener to print message from the host
// 2) Post document URL to the host
webview->AddScriptToExecuteOnDocumentCreated(
    L"window.chrome.webview.addEventListener(\'message\', event => alert(event.data));" \
    L"window.chrome.webview.postMessage(window.document.URL);",
    nullptr);
  • 호스트와 웹 콘텐츠의 통신도 가능하다 (postMessage)
  • Web -> Host
    • WebView2 컨트롤 내에서 실행되는 웹 콘텐츠는 메서드를 통해 호스트에 게실될 수 있으며 window.chrome.webview.postMessage는 호스트에 등록된 ICoreWebView2WebMessageReceivedEventHandler 이벤트 핸들러에 의해 처리된다
  • Host -> Web
    • ICoreWebView2::PostWebMessageAsString
    • ICoreWebView2::PostWebMessageAsJSON
    • 위 메서드를 통해 웹 콘텐츠에 메시지를 보낼 수 있으며 이 메시지는 리스너에 추가된 핸들러에 의해 포착된다
    • window.chrome.webview.addEventListener 이 통신 메커니즘을 사용하면 호스트에 기본 API를 실행하도록 요청하는 메시지를 전달하여 웹 콘텐츠가 기본 기능을 사용할 수 있다
  • 메커니즘을 이해하기 위한 예로 WebView2에서 문서 URL을 출력하려고하면 다음 단계가 발생한다
    • 호스트는 수신된 메시지를 웹 콘텐츠로 다시 반환하기 위한 핸들러를 등록합니다.
    • 호스트는 호스트에서 메시지를 인쇄하기 위해 핸들러를 등록하는 스크립트를 웹 콘텐츠에 삽입합니다.
    • 호스트는 호스트에 URL을 게시하는 웹 콘텐츠에 스크립트를 삽입합니다.
    • 호스트의 핸들러가 트리거되어 메시지(URL)를 웹 콘텐츠에 반환합니다.
    • 웹 콘텐츠의 핸들러가 트리거되고 호스트(URL)의 메시지를 인쇄합니다.
728x90

'Basic Programming > WebView2' 카테고리의 다른 글

WebView2 - 참고 사이트들  (0) 2024.05.19
728x90
728x90

'Basic Programming > WebView2' 카테고리의 다른 글

WebView2 - WebView2GettingStarted 코드 분석  (0) 2024.05.19
728x90
728x90

'Game Programming > Unity' 카테고리의 다른 글

Unity - SendMessage, BroadcastMessage, SendMessageUpwards  (0) 2017.06.12
Unity - OSVR 연동하기  (0) 2017.05.29
Unity - 단축키  (0) 2017.05.24
Unity - Logitech Extream 3D Pro 키 세팅  (0) 2017.05.23
Unity - 캐릭터 점프하기  (0) 2017.05.22
728x90

1. Epic Games Launcher 설치

EpicGames 홈페이지에서 Epic Games Launcher를 다운로드 받는다.

https://store.epicgames.com/en-US/

 

2. Unreal Engine 설치

Epic Games Launcher -> 라이브러리 -> 엔전 설치

 

언리얼 설치 후에 옵션에서 "디버깅을 위한 편집기 기호"를 추가적으로 설치하는 것을 추천한다. 
언리얼의 디버깅을 하려면 필요하다.

3. Visual Studio 2022 Community 설치

https://visualstudio.microsoft.com/ko/vs/community/ 에서 다운로드 후 설치

 

4. Visual Studio Installer를 이용해서 2022 필요한 기능 설치

아래 이미지에서 C++을 사용한 데스크톱 개발과 C++을 사용한 게임 개발 2개만 설치하면 된다.
나머지는 다른 것들을 개발하다보니 설치를 했다.

언어팩에서 영어 설치
언리얼 관련해서 인터넷 검색을 해보면 영어로된 자료가 더 많이 나오기 때문에 그냥 Visual Studio 2022의 설정을 영어로 하는 것을 추천한다.

 

5. 언리얼 세팅

Visual Studio 버전이 여러개가 설치되어있을 때 명시적으로 Visual Studio 2022의 버전을 지정해줘야한다.
여기에서 설정되면 모든 언리얼 프로젝트에 공통으로 적용된다.

 

 6. Visual Studio 2022 환경 세팅

옵션 -> 국가별 설정 -> 영어

 

옵션 -> 프로젝트 & 솔루션 -> Always show Error List if build finisheds with errors 체크 해제

 

Tools -> Customize -> Solution Configurations 의 길이 변경 (65 -> 200)

 

7. Visual Studio 2022 Extensions

아래와 같이 GENERATED_BODY() 매크로가 있는 상태에서 Enter Key를 누르면 들여쓰기가 되는데, 개발 중에 계속 들여쓰기가 되면 불편하기 때문에 확장 기능을 추가한다.

https://vlasovstudio.com/visual-commander/ 여기서 다운로드해서 설치하자.

그리고 https://github.com/hackalyze/ue4-vs-extensions 에서 다운로드하고 압축을 풀면 ue4_smarter_macro_indenting_vs2017-2019.vcmd 이런 파일이 있는데 이 파일을 2022에서도 쓸수있다.

Extensions -> Vcmd -> import -> ue4_smarter_macro_indenting_vs2017-2019.vcmd 하면 된다.

이후에 설치를 확인하고 싶으면 Extensions -> Vcmd -> Extensions 를 하면 아래와 같이 체크된 것을 확인할 수 있다.

728x90

'Game Programming > Unreal' 카테고리의 다른 글

Unreal5 문서  (0) 2023.09.17
Unreal - Unreal 4 Document  (0) 2016.12.02
728x90

다른 글 이외에 잡다하지만 유용해 보이는 것들에 대해 정리...

 

https://en.cppreference.com/w/cpp/utility/source_location

 

std::source_location - cppreference.com

struct source_location; (since C++20) The std::source_location class represents certain information about the source code, such as file names, line numbers, and function names. Previously, functions that desire to obtain this information about the call sit

en.cppreference.com

 

https://en.cppreference.com/w/cpp/utility/functional/bind_front

 

std::bind_front, std::bind_back - cppreference.com

template< class F, class... Args > constexpr /* unspecified */ bind_front( F&& f, Args&&... args ); (1) (since C++20) template< auto ConstFn, class... Args > constexpr /* unspecified */ bind_front( Args&&... args ); (2) (since C++26) template< class F, cla

en.cppreference.com

 

https://en.cppreference.com/w/cpp/types/is_constant_evaluated

 

std::is_constant_evaluated - cppreference.com

constexpr bool is_constant_evaluated() noexcept; (since C++20) Detects whether the function call occurs within a constant-evaluated context. Returns true if the evaluation of the call occurs within the evaluation of an expression or conversion that is mani

en.cppreference.com

 

https://en.cppreference.com/w/cpp/atomic/atomic_ref

 

std::atomic_ref - cppreference.com

template< class T > struct atomic_ref; (1) (since C++20) template< class T > struct atomic_ref ; (2) (since C++20) The std::atomic_ref class template applies atomic operations to the object it references. For the lifetime of the std::atomic_ref object, the

en.cppreference.com

 

https://en.cppreference.com/w/cpp/experimental/atomic_shared_ptr

 

std::experimental::atomic_shared_ptr - cppreference.com

Merged into ISO C++ The functionality described on this page was merged into the mainline ISO C++ standard as of 11/2017; see std::atomic > (since C++20) template< class T > class atomic_shared_ptr; (concurrency TS) The class template atomic_shared_ptr pro

en.cppreference.com

 

https://en.cppreference.com/w/cpp/thread/counting_semaphore

 

std::counting_semaphore, std::binary_semaphore - cppreference.com

template< std::ptrdiff_t LeastMaxValue = /* implementation-defined */ > class counting_semaphore; (1) (since C++20) using binary_semaphore = std::counting_semaphore<1>; (2) (since C++20) 1) A counting_semaphore is a lightweight synchronization primitive th

en.cppreference.com

 

https://en.cppreference.com/w/cpp/thread/latch

 

std::latch - cppreference.com

class latch; (since C++20) The latch class is a downward counter of type std::ptrdiff_t which can be used to synchronize threads. The value of the counter is initialized on creation. Threads may block on the latch until the counter is decremented to zero.

en.cppreference.com

 

https://en.cppreference.com/w/cpp/thread/barrier

 

std::barrier - cppreference.com

template< class CompletionFunction = /* see below */ > class barrier; (since C++20) The class template std::barrier provides a thread-coordination mechanism that blocks a group of threads of known size until all threads in that group have reached the barri

en.cppreference.com

 

 

https://en.cppreference.com/w/cpp/io/basic_osyncstream

 

std::basic_osyncstream - cppreference.com

The class template std::basic_osyncstream is a convenience wrapper for std::basic_syncbuf. It provides a mechanism to synchronize threads writing to the same stream. It can be used with a named variable: { std::osyncstream synced_out(std::cout); // synchro

en.cppreference.com

 

 

728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - jthread  (0) 2024.01.21
C++20 - format  (0) 2024.01.20
C++20 - Time Zone  (0) 2024.01.20
C++20 - Calendar  (0) 2024.01.17
C++20 - 비트연산  (0) 2024.01.17
728x90

그 동안 std::thread를 사용한 예제를 보면 다음과 같다

void ThreadWork()
{
    while(true)
    {
        // work...
    }
};

int main()
{
    std::thread t(ThreadWork);
    
    // 쓰레드가 종료되길 기다려줘야 한다.
    if (t.joinable())
    {
        t.join();
    }
}

 

이번에 jthread는 쉽게 말하면 소멸자에서 join을 해준다. 즉 위의 코드를 아래와 같이 변경할 수 있다.

void ThreadWork()
{
    while(true)
    {
        // work...
    }
};

int main()
{
    std::jthread t(ThreadWork);
}

 

 

하지만 위의 코드들은 thread가 종료되지 않는다. 종료되는 코드를 추가하면 다음과 같다.

bool gRunning =true;

void ThreadWork()
{
    while(gRunning)
    {
        // work...
    }
};

int main()
{
    std::thread t(ThreadWork);
    
    // 쓰레드 종료 요청
    gRunning = false;
    
    // 쓰레드가 종료되길 기다려줘야 한다.
    if (t.joinable())
    {
        t.join();
    }
}

 

jthread를 이용하면 조금 더 우아하게 종료할 수 있게 된다.

void ThreadWork(std::stop_token stopToken)
{
    while(true)
    {
        if (stopToken.stop_requested())
            break;
    }
};

int main()
{
    std::jthread t(ThreadWork);
    
    t.request_stop();
}

 

그 동안 사용했던 std::thread를 좀 더 관리하기 쉬워질 것 같다.

728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - 그 외 함수들...  (0) 2024.01.21
C++20 - format  (0) 2024.01.20
C++20 - Time Zone  (0) 2024.01.20
C++20 - Calendar  (0) 2024.01.17
C++20 - 비트연산  (0) 2024.01.17
728x90

C++을 좀 사용해보신분들은 이미 fmt::format을 많이 쓰고 있었을거라고 생각한다.

이제 동일한 기능이 C++20에도 포함이 되었다.

// format : format string 반환
auto str = std::format("{}, {}, {}", 1, 1.1, asdf);

// format_to : 결과를 output iterator에 반환
std::string buffer;
format_to(std::back_inserter(buffer), "{}, {}, {}", 1, 1.1, asdf);

// format_to_n : 최대 n개의 문자를 output iterator에 반환
std::string buffer2;
format_to(std::back_inserter(buffer2), 2, "{}, {}, {}", 1, 1.1, asdf);

 

만약 문자열에 "{" 를 사용하고 싶으면 {{ 와 같이 두개를 사용하면된다.

auto str = format("{{asdf {}}}", 5);

 

순서 지정하는 방법

format("{}, {}, {}", 10, 20, 30);
format("{1}, {0}, {2}", 10, 20, 30);

 

빈칸 채우는 문자 지정 (default : space)
정렬
 < left : 숫자가 아니면 default
 > right : 숫자면 default
 ^ center

format("{:10}", 5);   // "         5"
format("{:*<10}", 5); // "5*********"
format("{:*>10}", 5); // "*********5"
format("{:*^10}", 5); // "****5*****"

 

부호 (정수나 부동소수점에 사용)
 + : 양수면 + 붙여라
 - : 음수면 - 붙여라

format("{0:}, {0:+}, {0:-}", 0) // 0, +0, 0
format("{0:}, {0:+}, {0:-}", 1) // 1, +1, 1
format("{0:}, {0:+}, {0:-}", -1) // -1, -1, -1

 

정수에 대한 이진수, 팔진수, 십육진수 표현
 b : 이진수
 미지정 : 팔진수
 x : 십육진수
 #015 : 0을 15개의 padding 추가

format("#015", 0x78)  "000000000000120"
format("#015b", 0x78) "0b0000001111000"
format("#015x", 0x78) "0x0000000000078"

 

위에서 {:10} 은 최소 10개를 만든다는 뜻이었다. 반대로 최대 갯수도 지정할 수 있다.
precision 부동소수점과 문자열의 최대 갯수를 지정

double d = 123.456789;

format("{:.50}", d);            // "123.45678900000000555777....."
format("{:.8}", d);             // "123.45679" - 반올림됨
format("{:.5}", d);             // "123.46" - 반올림됨
format("{:.5}", "Hello World");	// "Hello"

 

타입 지정
 s : string
 b : binary 0b로 시작
 B : b와 같지만 0B로 시작
 d : decimal
 o : octal
 x : hexadecimal 0x로 시작
 X : x와 같지만 0X로 시작
 부동소수점 관련 (e, E, f, F ,g, G) : 생략... (지수 표시, 정밀도 등등...)


728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - 그 외 함수들...  (0) 2024.01.21
C++20 - jthread  (0) 2024.01.21
C++20 - Time Zone  (0) 2024.01.20
C++20 - Calendar  (0) 2024.01.17
C++20 - 비트연산  (0) 2024.01.17
728x90

전 세계에서 사용하는 프로그램을 개발할 때 시간이 관련된 작업을 하게 될 것이다.

이때 Local Time으로 시간 계산을 하게되면 나라마다의 시차를 계산하기 어려워진다.

그렇기 때문에 UTC(Coordinated Universal Time 협정 세계시)를 이용하여 시간을 계산하게 된다

- 영국 : UTC+0.00 (Greenwich Mean Time, GMT)
- 한국 : UTC+9.00
- 뉴욕 : UTC-5.00
...

이렇듯 각 나라마다 시간 계산을 해줘야하는데, 드디어 C++20에서 지원해주게 되었다.

using namespace std;
using namespace std::chrono;

auto utcTime :: system_clock::now();
cout << utcTime << endl;

auto localTime = zoned_time(current_zone(), utcTime);
cout << localTime << endl;

auto localTime2 = zoned_time("Asia/Shanghai"s, utcTime);
cout << localTime2 << endl;

 

추가로 유닉스 시간이라는 개념에 대해서 알아둬야한다.

유닉스 시간(Unix Time)은 시각을 나타내는 방식이고, POSIX, Epoch 시간이라고도 부른다.
1970년 1월 1일 00:00:00 협정 세계시(UTC) 부터의 경과 시간을 초로 환산하여 정수로 나타낸 것이다.

using namespace std;
using namespace std::chrono;

auto utcTime = system_clock::now();

int64_t hoursSinceUtc = duration<hours>(utcTime.time_since_epoch()).count();
int64_t utcEpoch = duration<seconds>(utcTime.time_since_epoch()).count();
728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - jthread  (0) 2024.01.21
C++20 - format  (0) 2024.01.20
C++20 - Calendar  (0) 2024.01.17
C++20 - 비트연산  (0) 2024.01.17
C++20 - erase, erase_if  (1) 2023.12.29

+ Recent posts