Initialize the SDK

The struct InitParam (declared in the zoom_sdk_def.h source file) is used as the parameter when you call the Init SDK API. One member of it is obConfigOpts which is also a struct. The value of the obConfigOpts.optionalFeatures function should be set to 32 to tell the server that you want to use the Customized UI service.


Initializing the SDK means that you want to use the Customized UI service. It does not mean that you have the license to use the service.

SDKinitParam.strWebDomain = strWebDomain.c_str();
SDKinitParam.obConfigOpts.optionalFeatures = (1 << 5); //Using Customized UI

//Using a boolean variable to record the return value of the InitSDK API is the simplest 
//way. 	If you want to handle more details here you can declare a variable with the 
//SDKError type, just like the following two lines.
//err = ZOOM_SDK_NAMESPACE::InitSDK(SDKinitParam); 

bool bInitSDK = ZOOM_SDK_NAMESPACE::InitSDK(SDKinitParam);

Create Customized UI Service and SetEvent

The customized UI service is dependent on the meeting service. You must create the meeting service first before the personalized UI service can be created.

It is recommended to create the meeting service when you receive the onMeetingStatusChanged notification with the parameter MeetingStatus equalling ZOOM_SDK_NAMESPACE::MEETING_STATUS_CONNECTING. This allows you to work with the preview meeting function as well.

ZOOM_SDK_NAMESPACE::CreateCustomizedUIMgr( & _ui_mgr);
if (_ui_mgr)
  _ui_mgr - > SetEvent(this);

Create Video Container, Video Element(s) and SetEvent

The video container is used to pack one or more video elements into one container. This allows you to create a highly customizable video layout. You can create one or more video containers as needed to create the UI you need.

After you create the Customized UI service successfully you should create a video container and SetEvent.

ui_mgr_->CreateVideoContainer(&_video_container, m_hOwnerHwnd, rc);
		if (NULL == _video_container)

		//a function to map the container, so your app knows which container should be handle
		CustomizedUIMgrWrap::GetInst().MapUIVideoContainer2SDKObj(this,				 _video_container); 

Make sure to always set the element type correctly when you create a video element for a container.

ZOOM_SDK_NAMESPACE::IVideoRenderElement * elem_ = NULL;
_video_container - > CreateVideoElement( & elem_, ZOOM_SDK_NAMESPACE::VideoRenderElement_ACTIVE);
_active_elem =
  dynamic_cast < ZOOM_SDK_NAMESPACE::IActiveVideoRenderElement * > (elem_);
if (_active_elem) {
  _active_elem - > Start();
  _active_elem - > Show();

Create Share Render and SetEvent

Share render is an operation used to implement annotation capabilities as well as other shared views. You should call the SetEvent function for the annotation controller.

ZOOM_SDK_NAMESPACE::ICustomizedAnnotationControllerEvent * anno_ctrl_cb = NULL;
if (meeting_service_) {
  anno_ctrl_cb = this;
if (_meeting_service - > GetAnnotationController() &&
  _meeting_service - > GetAnnotationController() - > GetCustomizedAnnotationController())
  _meeting_service - > GetAnnotationController() - > GetCustomizedAnnotationController() - > SetEvent(anno_ctrl_cb);

Create the share render. It’s recommended to create the share render and the video container together.

ui_mgr_->CreateShareRender(&_share_render, m_hOwnerHwnd, rc);
		if (NULL == _share_render)
		CustomizedUIMgrWrap::GetInst().MapUIShareRender2SDKObj(this,					 _share_render);

Remember to handle all of the event notifications. Since you are using a custom UI, the SDK cannot handle drawing or building your UI.

Preview Meeting

When joining a scheduled meeting that requires the host to start, you can show a preview of the user’s video before the meeting is started.

ZOOM_SDK_NAMESPACE::IVideoRenderElement * elem_ = NULL;
_video_container - > CreateVideoElement( & elem_, ZOOM_SDK_NAMESPACE::VideoRenderElement_PRVIEW);
_active_elem =
  dynamic_cast < ZOOM_SDK_NAMESPACE::IActiveVideoRenderElement * > (elem_);
if (_active_elem) {
  _active_elem - > Start();
  _active_elem - > Show();

Destroy Service

You should destroy all of the video elements video containers, annotation controllers, and share renders when you no longer need them.

if (_video_container)
  _video_container - > DestroyVideoElement(_preview_elem);

ZOOM_SDK_NAMESPACE::ICustomizedAnnotationController *
  anno_ctrl_ = _meeting_service - > GetAnnotationController() - > GetCustomizedAnnotationController();
if (anno_ctrl_) {
  if (_anno_obj) {
    _anno_obj - > SetEvent(NULL);
    anno_ctrl_ - > DestroyAnnoObj(_anno_obj);
    _anno_obj = NULL;
  if (_sending_sharing_anno_obj) {
    _sending_sharing_anno_obj - > SetEvent(NULL);
    anno_ctrl_ - > DestroyAnnoObj(_sending_sharing_anno_obj);
    _sending_sharing_anno_obj = NULL;
CustomizedUIMgrWrap::GetInst().GetSDKObj() - > DestroyAllVideoContainer();
CustomizedUIMgrWrap::GetInst().GetSDKObj() - > DestroyAllShareRender();

//Remember to destroy the service before the Meeting Service is destroied.

Helper Interfaces

The Windows SDK provides some helper interfaces. Below is a description on how to use the helper interfaces to build your custom UI.

InetworkConnectionHelper Class Reference

Two interfaces are used to detect Proxy Settings and SSL Verification. You should use these 2 interfaces to create a network-connection-helper before you call the SDK Auth. The SDK will use the helper to determine how to communicate with the Zoom meeting server.

Create Connection Helper:

static CNetwrokHelperSink s_networksink;
s_networksink.m_pDemo = this;
ZOOM_SDK_NAMESPACE::CreateNetworkConnectionHelper( & m_pNetworkConnectionHelper);
if (m_pNetworkConnectionHelper) {
  m_pNetworkConnectionHelper - > RegisterNetworkConnectionHandler( & s_networksink);

Destroy Connection Helper

if (m_pNetworkConnectionHelper) {
  m_pNetworkConnectionHelper = NULL;

SDK Version

Input the ZOOM_SDK_NAMESPACE::GetVersion() instance and the API will return information on the SDK version.


  • There is sample code in the SDK demo folder.
  • You can find API Docs in the Doc folder (Zoom SDK.chm).
  • All of the SDK APIs only work in the main UI thread.
  • We recommend you to check the return value for each API call.