키움증권 open api를 이용한 WinUi 앱 만들기

키움증권은 ocx로 작동하는 open api와 rest api를 제공한다. winui로 이용하기에는 후자가 편하지만 전자의 많은 기능들이 후자에는 없다.

ls증권의 dll을 이용하면 쉽게 winui 앱을 만들 수 있는데 앱 제작을 의뢰하시는 분이 굳이 키움증권의 api를 이용해 달라고 하는 경우가 있다. 코스피와 코스닥 대이터의 경우 키움증권의 api는 ls증권의 그것에 비해 성능이 나쁘고 개발하는 데 시간도 오래 걸린다. 이런 사정을 설명해도 키움증권의 api를 고집하면 만드는 사람 입장에서는 좋을 것도 싫을 것도 없다. 단지 의뢰하는 분 입장에서 비용만 늘어날 뿐이다.

키움증권의 open api는 wpf 프로젝트에도 설치할 수 없다. 설치하는 과정에 비주얼 스투디오가 크래쉬한다. 누게트 패키지로 있는 것도 제대로 작동하지 않는다. 천상 윈도우즈 폼즈에 설치해서 써야 한다.

winui 앱에서 키움증권 open api를 이용하는 과정은 번거롭지만 개념은 간단하다. 하나의 솔루션 아래에 winui 앱과 windows forms class library를 만든 뒤 전자에서 후자를 불러다 쓰면 된다.

WinUi 앱과 windows forms class library를 만들기

winui 앱을 만든 뒤 솔루션에 윈도우즈 폼즈 클래스 라이브러리를 추가한다. 윈도우즈 폼즈 애플리캐이션을 만들고 빌드하면 실행 파일을 만들지만 클래스 라이브러리를 빌드하면 dll을 만든다.

UserControl 만들기

ocx를 설치하기 위해 윈도우즈 폼즈 클래스 라이브러리에 UserControl을 추가한다. 윈도우즈 폼즈 클래스 라이브러리를 만들 때 자동으로 생긴 class1.cs는 지운다.

윈도우즈 폼즈 클래스 라이브러리를 x86으로 바꾼다. 그러면 toolbox에 khopenapi control이 나타단다. 이걸 UserControl에 만든다. 그러면 axkhOpenapi1가 생긴다.

namespace WinFormsLibrary1
{
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        public void Connect()
        {
            axkhOpenapi1.CommConnect();
        }
    }
}

위의 접속 코드를 만들고 WinFormsLibrary1를 빌드한다. 빌드를 해야 dll이 생겨서 WinUi가 참조할 수 있다.

WinUi 앱이 윈도우즈 폼즈 클래스 라이브러리 참조하기

solution explorer > App1 > add > project reference > WinFormsLibrary1

위의 참조를 하고 App1을 빌드한다. 그러면 비주얼 스투디오 2026의 경우 에러들이 생길 거다. 현재 버전의 경우 WinUi 앱을 만들면 target framework가 .net 8.0이고 윈도우즈 폼즈 클래스 라이브러리의 경우 10.0이다. 이들이 달라서 생긴 오류이므로 프로젝트 프라퍼티즈에서 전자를 10으로 바꾼다. 그러면 제대로 빌드한다.

참조를 하고 빌드를 하면 WinFormsLibrary1 내임스패이스를 쓸 수 있게 된다.

<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="App1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="App1">

    <Window.SystemBackdrop>
        <MicaBackdrop />
    </Window.SystemBackdrop>

    <Grid>
        <Button Content="test" Click="Button_Click"/>
    </Grid>
</Window>
using Microsoft.UI.Xaml;
using WinFormsLibrary1;

namespace App1
{
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            UserControl1 kiwoom = new();

            kiwoom.Connect();
        }
    }
}

버튼을 클릭하면 로그인 창이 뜬다. 된 거다.

아래는 이벤트 예제다.

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();

        axkhOpenapi1.OnEventConnect += AxkhOpenapi1_OnEventConnect;
    }

    public event EventHandler<int> Connected;

    private void AxkhOpenapi1_OnEventConnect(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnEventConnectEvent e)
    {
        Connected?.Invoke(this, e.nErrCode);
    }

...
using Microsoft.UI.Xaml;
using WinFormsLibrary1;

namespace App1
{
    public sealed partial class MainWindow : Window
    {
        UserControl1 Kiwoom;

        public MainWindow()
        {
            InitializeComponent();

            Kiwoom = new();

            Kiwoom.Connected += Kiwoom_Connected;
        }

        private void Kiwoom_Connected(object? sender, int e)
        {
            Title = "connected";
        }

...