SAP GUI 화면에서 트리(Tree) 의 항목을 마우스로 끌어다 텍스트 편집기(TextEdit) 에 떨어뜨리면 그 내용이 입력되는 드래그앤드롭(Drag & Drop) UI 를 만들 수 있습니다. 왼쪽 트리에서 항목을 선택해 오른쪽 편집기로 끌어다 놓는, 직관적인 양식 작성 화면이 대표적인 예입니다.
이 기능의 핵심은 CL_DRAGDROP 라는 "동작(behavior) 정의 객체" 입니다. "이 컨트롤은 드래그 출발지인가 / 드롭 목적지인가", "복사인가 이동인가", "어떤 종류(flavor) 의 데이터인가" 를 미리 정의해두고, 트리 노드와 편집기에 각각 연결합니다. 그리고 실제 드래그·드롭 순간에 발생하는 이벤트를 핸들러로 받아 데이터를 주고받습니다.
이 글에서는 컨테이너 계층(Easy Splitter 좌우 분할) → CL_DRAGDROP behavior 정의 → 트리/편집기 연결 → 이벤트 핸들러 → flavor 메커니즘까지 정리합니다. 데이터는 모두 가상 예시값입니다.
핵심 — 컨테이너 계층과 drag&drop 4요소
화면 구조는 Easy Splitter 로 좌(트리) / 우(편집기) 를 나눕니다.
Screen 100
└ Custom Control 'CONTAINER'
└ g_container (cl_gui_custom_container)
└ g_splitter (cl_gui_easy_splitter_container · 수직 분할)
├ top_left_container ← g_tree (cl_gui_simple_tree)
└ bottom_right_container ← g_textedit (cl_gui_textedit)
drag&drop 을 구성하는 4가지 요소는 다음과 같습니다.
| 요소 | 클래스/개념 | 역할 |
|---|---|---|
| Behavior | cl_dragdrop |
드래그/드롭 동작 규칙 정의 (출발지·목적지·효과) |
| Flavor | cndd_flavor |
데이터 종류 구분 (Head/Body/Letter 등) |
| Data Object | 로컬 클래스 (예: lcl_dragdrop_dataobject) |
실제로 옮길 데이터를 담는 그릇 |
| Event Handler | on_drag·on_drop 등 |
드래그·드롭 순간의 동작 처리 |
핵심 흐름: 트리 노드를 끌면 on_drag 이벤트에서 데이터 객체를 실어 보내고, 편집기에 놓으면 on_drop 이벤트에서 그 데이터를 꺼내 편집기에 삽입합니다.
1단계 — 컨테이너 + TREE + TEXTEDIT 생성
Easy Splitter 로 화면을 좌우로 나누고, 왼쪽엔 트리, 오른쪽엔 편집기를 붙입니다.
FORM create_container.
g_container = NEW #( container_name = 'CONTAINER' ).
g_splitter = NEW #(
parent = g_container
orientation = 1 ). " 수직 분할(좌/우)
g_splitter->set_sash_position( sash_position = 30 ). " 왼쪽 30%
* 오른쪽 — 텍스트 편집기
g_textedit = NEW #(
parent = g_splitter->bottom_right_container
wordwrap_mode = cl_gui_textedit=>wordwrap_at_windowborder
wordwrap_to_linebreak_mode = cl_gui_textedit=>false ).
* 왼쪽 — 심플 트리
g_tree = NEW #(
parent = g_splitter->top_left_container
node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).
ENDFORM.
wordwrap_at_windowborder 는 창 너비에서 자동 줄바꿈, node_sel_mode_single 은 트리 단일 선택 모드.
2단계 — CL_DRAGDROP behavior 정의
드래그앤드롭의 규칙을 CL_DRAGDROP 객체에 등록합니다. add 메소드로 "어떤 flavor 를, 드래그 출발지로 쓸지(dragsrc), 드롭 목적지로 쓸지(droptarget), 효과는 복사/이동 중 무엇인지(effect)" 를 정의합니다.
DATA l_effect TYPE i.
* 편집기 — 드롭 목적지 (Head/Body 받음, 복사+이동 모두 허용)
g_behaviour_textedit = NEW #( ).
l_effect = cl_dragdrop=>copy + cl_dragdrop=>move. " 1 + 2
g_behaviour_textedit->add(
EXPORTING
flavor = g_dragdrop_flavor_head " 'Head'
dragsrc = ' ' " 출발지 아님
droptarget = 'X' " 목적지 O
effect = l_effect ).
* 트리 Head 노드 — 드래그 출발지 (복사+이동)
g_behaviour_tree_head = NEW #( ).
g_behaviour_tree_head->add(
EXPORTING
flavor = g_dragdrop_flavor_head
dragsrc = 'X' " 출발지 O
droptarget = ' ' " 목적지 아님
effect = cl_dragdrop=>copy + cl_dragdrop=>move ).
CL_DRAGDROP 의 효과(effect) 상수는 다음과 같습니다.
| 상수 | 값 | 의미 |
|---|---|---|
cl_dragdrop=>none |
0 | 효과 없음 |
cl_dragdrop=>copy |
1 | 복사 (원본 유지) |
cl_dragdrop=>move |
2 | 이동 (원본 삭제) |
copy + move |
3 | 복사·이동 둘 다 허용 (Ctrl 키로 전환) |
값을 합산(copy + move = 3) 하면 두 효과를 모두 허용한다는 뜻입니다.
3단계 — behavior 를 컨트롤/노드에 연결
정의한 behavior 를 편집기와 트리 노드에 할당합니다. 편집기는 set_dragdrop 으로, 트리 노드는 get_handle 로 얻은 핸들을 노드의 dragdropid 에 넣습니다.
* 편집기에 behavior 연결
g_textedit->set_dragdrop( dragdrop = g_behaviour_textedit ).
* 트리 노드용 behavior 핸들 획득
DATA l_handle_tree_head TYPE i.
g_behaviour_tree_head->get_handle( IMPORTING handle = l_handle_tree_head ).
* 노드 정의 시 dragdropid 에 핸들 할당
DATA l_node LIKE mtreesnode.
l_node-node_key = '1RChild1'.
l_node-relatkey = '1Root'.
l_node-relatship = cl_gui_simple_tree=>relat_last_child.
l_node-text = 'Mr. Hong'.
l_node-dragdropid = l_handle_tree_head. " ★ 이 노드의 드래그 동작 = head behavior
APPEND l_node TO g_node_table.
* 트리에 노드 일괄 추가
g_tree->add_nodes(
EXPORTING
table_structure_name = 'MTREESNODE'
node_table = g_node_table
EXCEPTIONS
failed = 1
error_in_node_table = 2
OTHERS = 5 ).
각 노드의 dragdropid 에 어떤 behavior 핸들을 넣느냐에 따라, 그 노드가 어떤 flavor 로 드래그되는지가 결정됩니다.
4단계 — 이벤트 핸들러 등록
드래그·드롭 순간의 동작을 처리할 핸들러를 SET HANDLER 로 연결합니다.
g_event_receiver = NEW #( ).
SET HANDLER g_event_receiver->handle_tree_drag FOR g_tree. " 트리 드래그 시작
SET HANDLER g_event_receiver->handle_tree_drop_complete FOR g_tree. " 드롭 완료(move 처리)
SET HANDLER g_event_receiver->select_textedit_flavor FOR g_textedit. " 드롭 위치별 flavor 결정
SET HANDLER g_event_receiver->handle_textedit_drop FOR g_textedit. " 편집기에 데이터 삽입
g_textedit->register_event_dblclick( ).
SET HANDLER g_event_receiver->handle_textedit_doubleclick FOR g_textedit.
각 이벤트의 역할은 다음과 같습니다.
| 이벤트 | 발생 컨트롤 | 처리 내용 |
|---|---|---|
on_drag |
트리 | 끌린 노드의 데이터 객체를 drag_drop_object->object 에 실음 |
on_get_flavor |
편집기 | 드롭 위치(줄 번호) 에 따라 받을 flavor 결정 |
on_drop |
편집기 | 데이터 객체를 꺼내 set_selected_text_as_r3table 로 삽입 |
on_drop_complete |
트리 | 효과가 move 면 원본 노드 삭제 |
flavor 메커니즘 — 같은 드래그, 다른 처리
flavor 는 "같은 드래그 동작이라도 데이터 종류에 따라 다르게 처리" 하기 위한 꼬리표입니다. 예를 들어 편집기 첫 줄(제목 영역) 에는 Head flavor 만 받고, 본문 영역에는 Body flavor 를 받도록 구분할 수 있습니다.
* 드롭 위치(줄 번호) 에 따라 받을 flavor 를 결정
METHOD select_textedit_flavor.
IF line = 1. " 첫 줄이면
SEARCH flavors FOR g_dragdrop_flavor_head. " Head 가능한지 확인
IF sy-subrc EQ 0.
dragdrop_object->set_flavor( newflavor = g_dragdrop_flavor_head ).
ELSE.
dragdrop_object->abort( ). " 안 되면 드롭 취소
ENDIF.
ENDIF.
ENDMETHOD.
* 실제 드롭 시 flavor 에 따라 다른 데이터 삽입
METHOD handle_textedit_drop.
DATA l_dataobj TYPE REF TO lcl_dragdrop_dataobject.
CATCH SYSTEM-EXCEPTIONS move_cast_error = 1.
l_dataobj ?= dragdrop_object->object. " 데이터 객체 꺼내기
ENDCATCH.
IF sy-subrc EQ 1.
dragdrop_object->abort( ).
EXIT.
ENDIF.
CASE dragdrop_object->flavor.
WHEN g_dragdrop_flavor_head. " Head → 제목 데이터 삽입
sender->set_selected_text_as_r3table( table = l_dataobj->head ).
WHEN g_dragdrop_flavor_body. " Body → 본문 데이터 삽입
sender->set_selected_text_as_r3table( table = l_dataobj->body ).
ENDCASE.
ENDMETHOD.
같은 데이터 객체라도 어떤 flavor 로 드롭됐는지에 따라 head 를 넣을지 body 를 넣을지 분기합니다.
자주 빠뜨리는 함정
get_handle 호출 시점
get_handle 은 behavior 를 프런트엔드로 전송하도록 표시하는 역할도 합니다. 노드의 dragdropid 에 넣기 전에 반드시 핸들을 먼저 얻어야 합니다.
move_cast_error 미처리
on_drop 에서 dragdrop_object->object 를 데이터 객체로 다운캐스팅(?=) 할 때, 예상과 다른 객체가 오면 캐스팅 에러가 납니다. 반드시 CATCH SYSTEM-EXCEPTIONS move_cast_error 로 감싸고, 실패 시 abort( ) 해야 합니다.
dragsrc / droptarget 방향 혼동
드래그 출발지는 dragsrc = 'X', 드롭 목적지는 droptarget = 'X'. 트리는 출발지, 편집기는 목적지로 방향을 맞춰야 합니다. 둘 다 잘못 주면 드래그가 시작되지 않거나 드롭이 안 됩니다.
move 효과인데 원본 삭제 누락
효과를 move 로 허용했다면 on_drop_complete 에서 원본 트리 노드를 delete_node 로 지워야 "이동" 이 완성됩니다. 안 지우면 복사처럼 보입니다.
컨테이너 생성 가드
PBO 의 IF g_container IS INITIAL 가드 없이 매번 생성하면 컨트롤·이벤트가 중복 등록되어 동작이 꼬입니다.
전체 코드 — 복사용 통합본
아래는 INCLUDE 로 나뉜 원본을 단일 프로그램으로 합친 통합본입니다. SE38 에 붙이고 SE51 에서 Screen 100 에 Custom Control 'CONTAINER' 를 그린 뒤, Flow Logic 에 status_0100 · container (PBO) · user_command_0100 (PAI) 를 연결하면 됩니다. 데이터 텍스트는 모두 가상 예시값.
*&---------------------------------------------------------------------*
*& Report ZRXX_TEXT_TREE_DND (예시)
*&---------------------------------------------------------------------*
*& TEXTEDIT + SIMPLE TREE 드래그앤드롭
*&---------------------------------------------------------------------*
REPORT zrxx_text_tree_dnd.
* ── 전역 선언 ───────────────────────────────────────────────
CLASS lcl_event_receiver DEFINITION DEFERRED.
CLASS lcl_dragdrop_dataobject DEFINITION DEFERRED.
CONSTANTS g_line_length TYPE i VALUE 50.
DATA: g_container TYPE REF TO cl_gui_custom_container,
g_splitter TYPE REF TO cl_gui_easy_splitter_container,
g_tree TYPE REF TO cl_gui_simple_tree,
g_textedit TYPE REF TO cl_gui_textedit.
DATA: g_behaviour_tree_head TYPE REF TO cl_dragdrop,
g_behaviour_tree_body TYPE REF TO cl_dragdrop,
g_behaviour_tree_letter TYPE REF TO cl_dragdrop,
g_behaviour_textedit TYPE REF TO cl_dragdrop.
DATA: g_event_receiver TYPE REF TO lcl_event_receiver,
g_datapool TYPE TABLE OF REF TO lcl_dragdrop_dataobject.
TYPES: g_textline_type(g_line_length) TYPE c,
g_texttable_type TYPE TABLE OF g_textline_type.
DATA: g_ok_code TYPE sy-ucomm,
g_node_table TYPE TABLE OF mtreesnode.
CONSTANTS: g_dragdrop_flavor_head TYPE cndd_flavor VALUE 'Head',
g_dragdrop_flavor_body TYPE cndd_flavor VALUE 'Body',
g_dragdrop_flavor_letter TYPE cndd_flavor VALUE 'Letter'.
* ── 데이터 객체 클래스 ──────────────────────────────────────
CLASS lcl_dragdrop_dataobject DEFINITION.
PUBLIC SECTION.
DATA: text TYPE g_texttable_type,
head TYPE g_texttable_type,
body TYPE g_texttable_type.
ENDCLASS.
CLASS lcl_dragdrop_dataobject IMPLEMENTATION.
ENDCLASS.
* ── 이벤트 핸들러 클래스 ────────────────────────────────────
CLASS lcl_event_receiver DEFINITION.
PUBLIC SECTION.
METHODS handle_textedit_drop FOR EVENT on_drop OF cl_gui_textedit
IMPORTING index line pos dragdrop_object sender.
METHODS select_textedit_flavor FOR EVENT on_get_flavor OF cl_gui_textedit
IMPORTING index line pos flavors dragdrop_object.
METHODS handle_tree_drag FOR EVENT on_drag OF cl_gui_simple_tree
IMPORTING node_key drag_drop_object.
METHODS handle_tree_drop_complete FOR EVENT on_drop_complete OF cl_gui_simple_tree
IMPORTING node_key drag_drop_object sender.
METHODS handle_textedit_doubleclick FOR EVENT dblclick OF cl_gui_textedit
IMPORTING sender.
ENDCLASS.
CLASS lcl_event_receiver IMPLEMENTATION.
METHOD handle_textedit_drop.
DATA l_dataobj TYPE REF TO lcl_dragdrop_dataobject.
CATCH SYSTEM-EXCEPTIONS move_cast_error = 1.
l_dataobj ?= dragdrop_object->object.
ENDCATCH.
IF sy-subrc EQ 1.
dragdrop_object->abort( ).
EXIT.
ENDIF.
CASE dragdrop_object->flavor.
WHEN g_dragdrop_flavor_head.
sender->set_selected_text_as_r3table(
EXPORTING table = l_dataobj->head
EXCEPTIONS error_dp = 1 error_dp_create = 2 ).
WHEN g_dragdrop_flavor_body.
sender->set_selected_text_as_r3table(
EXPORTING table = l_dataobj->body
EXCEPTIONS error_dp = 1 error_dp_create = 2 ).
ENDCASE.
ENDMETHOD.
METHOD select_textedit_flavor.
IF line = 1.
SEARCH flavors FOR g_dragdrop_flavor_head.
IF sy-subrc EQ 0.
dragdrop_object->set_flavor( newflavor = g_dragdrop_flavor_head ).
ELSE.
dragdrop_object->abort( ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD handle_tree_drag.
DATA: l_dataobj TYPE REF TO lcl_dragdrop_dataobject,
l_index TYPE c.
CASE node_key.
WHEN '1RChild1'. l_index = 1.
WHEN '1RChild2'. l_index = 2.
WHEN '2RChild1'. l_index = 1.
ENDCASE.
READ TABLE g_datapool INDEX l_index INTO l_dataobj.
IF sy-subrc EQ 0.
drag_drop_object->object = l_dataobj.
ENDIF.
ENDMETHOD.
METHOD handle_tree_drop_complete.
IF drag_drop_object->effect = cl_dragdrop=>move.
sender->delete_node( node_key = node_key ).
DELETE g_node_table WHERE node_key = node_key.
ENDIF.
ENDMETHOD.
METHOD handle_textedit_doubleclick.
sender->set_status_text( status_text = '텍스트를 더블클릭하셨습니다' ).
ENDMETHOD.
ENDCLASS.
* ── 실행 ────────────────────────────────────────────────────
START-OF-SELECTION.
CALL SCREEN 100.
* ── PBO ─────────────────────────────────────────────────────
MODULE status_0100 OUTPUT.
SET PF-STATUS 'S100'.
ENDMODULE.
MODULE container OUTPUT.
IF g_container IS INITIAL.
PERFORM create_container.
PERFORM create_dragdrop.
PERFORM assign_dragdrop.
PERFORM event_dragdrop.
PERFORM node_data.
ENDIF.
ENDMODULE.
* ── PAI ─────────────────────────────────────────────────────
MODULE user_command_0100 INPUT.
CASE g_ok_code.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
ENDCASE.
ENDMODULE.
* ── 1) 컨테이너 + Tree + TextEdit 생성 ──────────────────────
FORM create_container.
g_container = NEW #( container_name = 'CONTAINER' ).
g_splitter = NEW #( parent = g_container orientation = 1 ).
g_splitter->set_sash_position( sash_position = 30 ).
g_textedit = NEW #(
parent = g_splitter->bottom_right_container
wordwrap_mode = cl_gui_textedit=>wordwrap_at_windowborder
wordwrap_to_linebreak_mode = cl_gui_textedit=>false ).
g_tree = NEW #(
parent = g_splitter->top_left_container
node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).
ENDFORM.
* ── 2) drag&drop behavior 정의 ──────────────────────────────
FORM create_dragdrop.
DATA l_effect TYPE i.
* 편집기 — 드롭 목적지 (Head/Body/Letter 받음)
g_behaviour_textedit = NEW #( ).
l_effect = cl_dragdrop=>copy + cl_dragdrop=>move.
g_behaviour_textedit->add( EXPORTING flavor = g_dragdrop_flavor_head
dragsrc = ' ' droptarget = 'X' effect = l_effect ).
g_behaviour_textedit->add( EXPORTING flavor = g_dragdrop_flavor_body
dragsrc = ' ' droptarget = 'X' effect = l_effect ).
g_behaviour_textedit->add( EXPORTING flavor = g_dragdrop_flavor_letter
dragsrc = ' ' droptarget = 'X' effect = l_effect ).
* 트리 Head — 드래그 출발지 (복사+이동)
g_behaviour_tree_head = NEW #( ).
l_effect = cl_dragdrop=>copy + cl_dragdrop=>move.
g_behaviour_tree_head->add( EXPORTING flavor = g_dragdrop_flavor_head
dragsrc = 'X' droptarget = ' ' effect = l_effect ).
* 트리 Body — 드래그 출발지 (복사만)
g_behaviour_tree_body = NEW #( ).
l_effect = cl_dragdrop=>copy.
g_behaviour_tree_body->add( EXPORTING flavor = g_dragdrop_flavor_body
dragsrc = 'X' droptarget = ' ' effect = l_effect ).
* 트리 Letter — 드래그 출발지 (Head/Body/Letter 모두)
g_behaviour_tree_letter = NEW #( ).
l_effect = cl_dragdrop=>copy.
g_behaviour_tree_letter->add( EXPORTING flavor = g_dragdrop_flavor_letter
dragsrc = 'X' droptarget = ' ' effect = l_effect ).
g_behaviour_tree_letter->add( EXPORTING flavor = g_dragdrop_flavor_head
dragsrc = 'X' droptarget = ' ' effect = l_effect ).
g_behaviour_tree_letter->add( EXPORTING flavor = g_dragdrop_flavor_body
dragsrc = 'X' droptarget = ' ' effect = l_effect ).
ENDFORM.
* ── 3) behavior 연결 + 노드 빌드 ────────────────────────────
FORM assign_dragdrop.
g_textedit->set_dragdrop( dragdrop = g_behaviour_textedit ).
PERFORM build_node_table.
ENDFORM.
FORM build_node_table.
DATA: l_node LIKE mtreesnode,
l_handle_tree_head TYPE i,
l_handle_tree_body TYPE i,
l_handle_tree_letter TYPE i.
g_behaviour_tree_head->get_handle( IMPORTING handle = l_handle_tree_head ).
g_behaviour_tree_body->get_handle( IMPORTING handle = l_handle_tree_body ).
g_behaviour_tree_letter->get_handle( IMPORTING handle = l_handle_tree_letter ).
CLEAR l_node.
l_node-node_key = '1Root'. l_node-isfolder = 'X'.
l_node-text = 'Letter head (copy & move)'.
APPEND l_node TO g_node_table.
CLEAR l_node.
l_node-node_key = '1RChild1'. l_node-relatkey = '1Root'.
l_node-relatship = cl_gui_simple_tree=>relat_last_child.
l_node-text = 'Mr. Hong'.
l_node-dragdropid = l_handle_tree_head.
APPEND l_node TO g_node_table.
CLEAR l_node.
l_node-node_key = '1RChild2'. l_node-relatkey = '1Root'.
l_node-relatship = cl_gui_simple_tree=>relat_last_child.
l_node-text = 'Mr. Kim'.
l_node-dragdropid = l_handle_tree_head.
APPEND l_node TO g_node_table.
CLEAR l_node.
l_node-node_key = '2Root'. l_node-isfolder = 'X'.
l_node-text = 'Letter Bodies (copy only)'.
APPEND l_node TO g_node_table.
CLEAR l_node.
l_node-node_key = '2RChild1'. l_node-relatkey = '2Root'.
l_node-relatship = cl_gui_simple_tree=>relat_last_child.
l_node-text = 'Sample Body Text'.
l_node-dragdropid = l_handle_tree_body.
APPEND l_node TO g_node_table.
g_tree->add_nodes(
EXPORTING
table_structure_name = 'MTREESNODE'
node_table = g_node_table
EXCEPTIONS
failed = 1 error_in_node_table = 2 dp_error = 3
table_structure_name_not_found = 4 OTHERS = 5 ).
g_tree->expand_node( node_key = '1Root' ).
g_tree->expand_node( node_key = '2Root' ).
ENDFORM.
* ── 4) 이벤트 핸들러 등록 ───────────────────────────────────
FORM event_dragdrop.
g_event_receiver = NEW #( ).
SET HANDLER g_event_receiver->handle_textedit_drop FOR g_textedit.
SET HANDLER g_event_receiver->select_textedit_flavor FOR g_textedit.
SET HANDLER g_event_receiver->handle_tree_drag FOR g_tree.
SET HANDLER g_event_receiver->handle_tree_drop_complete FOR g_tree.
g_textedit->register_event_dblclick( ).
SET HANDLER g_event_receiver->handle_textedit_doubleclick FOR g_textedit.
ENDFORM.
* ── 데이터 풀 채우기 (가상 예시값) ──────────────────────────
FORM node_data.
DATA: l_first TYPE REF TO lcl_dragdrop_dataobject,
l_second TYPE REF TO lcl_dragdrop_dataobject,
l_textline TYPE g_textline_type.
l_first = NEW #( ).
l_second = NEW #( ).
l_textline = '홍길동'.
APPEND l_textline TO l_first->head.
l_textline = '입사를 진심으로 축하합니다.'.
APPEND l_textline TO l_first->head.
APPEND l_first TO g_datapool.
l_textline = '자재 등급 판정'.
APPEND l_textline TO l_second->head.
l_textline = '해당 자재 TEST-MAT-001 는 등급 A1 입니다.'.
APPEND l_textline TO l_second->head.
APPEND l_second TO g_datapool.
l_textline = 'Sample body line 1'.
APPEND l_textline TO l_first->body.
l_textline = 'Sample body line 2'.
APPEND l_textline TO l_first->body.
APPEND l_first TO g_datapool.
ENDFORM.

요약
| 단계 | FORM | 핵심 행동 |
|---|---|---|
| 1 | create_container |
Easy Splitter 좌(Tree) / 우(TextEdit) 분할 |
| 2 | create_dragdrop |
cl_dragdrop behavior 정의 (flavor·dragsrc·droptarget·effect) |
| 3 | assign_dragdrop + build_node_table |
set_dragdrop + 노드 dragdropid 에 핸들 할당 |
| 4 | event_dragdrop |
SET HANDLER 로 on_drag·on_drop 등 연결 |
| 5 | node_data |
각 노드에 대응하는 데이터 객체 적재 |
TextEdit + Tree 드래그앤드롭의 본질은 "cl_dragdrop 으로 동작 규칙을 정의하고, flavor 로 데이터 종류를 구분하고, on_drag/on_drop 이벤트로 데이터를 실어 보내고 꺼내는 것". 출발지(트리) 와 목적지(편집기) 의 dragsrc/droptarget 방향만 정확히 맞추면, 같은 패턴으로 ALV ↔ Tree, Tree ↔ Tree 등 다양한 컨트롤 간 드래그앤드롭에 응용할 수 있습니다.
Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다.
CL_DRAGDROP 의 효과 상수(copy=1·move=2·none=0) 와 add/get_handle 시그니처, CL_GUI_TEXTEDIT·CL_GUI_SIMPLE_TREE 의 이벤트는 NetWeaver 표준 정의(ECC 6.0 / S/4HANA on-premise 기준) 입니다. 적용 환경 버전에 따라 일부 차이가 있을 수 있으니 실제 적용 시 SE24 의 클래스 정의를 확인하시기 바랍니다. 본문 데이터 텍스트는 모두 가상 예시값입니다.