eliza gui chatbot (win32lib)

new topic     » topic index » view thread      » older message » newer message

Hi again - I decided to code Euphoria, an implementation of ELIZA (eliza.ex) with a GUI using win32lib here is the result... eliza.ex

-- Complete ELIZA Chatbot with Win32 GUI 
-- Euphoria 4.x - Save as eliza.ex and compile with euc eliza.ex 
 
include std/dll.e 
include std/machine.e 
include std/sequence.e 
 
-- Win32 API constants 
constant  
    WS_OVERLAPPEDWINDOW = #00CF0000, 
    WS_VISIBLE = #10000000, 
    WS_CHILD = #40000000, 
    WS_BORDER = #00800000, 
    WS_VSCROLL = #00200000, 
    ES_MULTILINE = #0004, 
    ES_READONLY = #0800, 
    ES_AUTOVSCROLL = #0040, 
    BS_PUSHBUTTON = #00000000, 
    BS_DEFPUSHBUTTON = #00000001, 
     
    WM_CREATE = #0001, 
    WM_DESTROY = #0002, 
    WM_COMMAND = #0111, 
    WM_CLOSE = #0010, 
    WM_SIZE = #0005, 
    WM_KEYDOWN = #0100, 
    WM_CHAR = #0102, 
     
    VK_RETURN = #0D, 
    FVIRTKEY = #01, 
     
    SW_SHOWNORMAL = 1, 
     
    EM_SETSEL = #00B1, 
    EM_SCROLLCARET = #00B7, 
     
    ID_EDIT_INPUT = 1001, 
    ID_EDIT_OUTPUT = 1002, 
    ID_BUTTON_SEND = 1003, 
    ID_BUTTON_CLEAR = 1004, 
    ID_ACCEL_ENTER = 1005 
 
-- Win32 API functions (defined once only) 
atom user32 = open_dll("user32.dll") 
atom kernel32 = open_dll("kernel32.dll") 
 
atom CreateWindowExA = define_c_func(user32, "CreateWindowExA",  
    {C_DWORD, C_POINTER, C_POINTER, C_DWORD, C_INT, C_INT, C_INT, C_INT,  
     C_POINTER, C_POINTER, C_POINTER, C_POINTER}, C_POINTER) 
atom ShowWindow = define_c_func(user32, "ShowWindow", {C_POINTER, C_INT}, C_INT) 
atom UpdateWindow = define_c_func(user32, "UpdateWindow", {C_POINTER}, C_INT) 
atom GetMessageA = define_c_func(user32, "GetMessageA",  
    {C_POINTER, C_POINTER, C_UINT, C_UINT}, C_INT) 
atom TranslateMessage = define_c_func(user32, "TranslateMessage", {C_POINTER}, C_INT) 
atom DispatchMessageA = define_c_func(user32, "DispatchMessageA", {C_POINTER}, C_LONG) 
atom PostQuitMessage = define_c_proc(user32, "PostQuitMessage", {C_INT}) 
atom DefWindowProcA = define_c_func(user32, "DefWindowProcA",  
    {C_POINTER, C_UINT, C_POINTER, C_LONG}, C_LONG) 
atom RegisterClassA = define_c_func(user32, "RegisterClassA", {C_POINTER}, C_INT) 
atom LoadCursorA = define_c_func(user32, "LoadCursorA", {C_POINTER, C_POINTER}, C_POINTER) 
atom GetWindowTextA = define_c_func(user32, "GetWindowTextA",  
    {C_POINTER, C_POINTER, C_INT}, C_INT) 
atom SetWindowTextA = define_c_func(user32, "SetWindowTextA",  
    {C_POINTER, C_POINTER}, C_INT) 
atom GetModuleHandleA = define_c_func(kernel32, "GetModuleHandleA", {C_POINTER}, C_POINTER) 
atom MoveWindow = define_c_func(user32, "MoveWindow",  
    {C_POINTER, C_INT, C_INT, C_INT, C_INT, C_INT}, C_INT) 
atom SendMessageA = define_c_func(user32, "SendMessageA",  
    {C_POINTER, C_UINT, C_POINTER, C_LONG}, C_LONG) 
atom GetFocus = define_c_func(user32, "GetFocus", {}, C_POINTER) 
atom CreateAcceleratorTableA = define_c_func(user32, "CreateAcceleratorTableA",  
    {C_POINTER, C_INT}, C_POINTER) 
atom TranslateAcceleratorA = define_c_func(user32, "TranslateAcceleratorA",  
    {C_POINTER, C_POINTER, C_POINTER}, C_INT) 
 
-- Global variables 
atom hwnd_main, hwnd_input, hwnd_output, hwnd_send, hwnd_clear 
atom h_accel_table = 0 
sequence chat_history = {} 
 
-- ELIZA patterns with priorities (expanded database) 
sequence eliza_patterns = { 
    -- Greetings and farewells (priority 10) 
    {10, "hello*", {"Hello! I'm glad you came to talk with me.", "Hello there! How are you feeling today?", "Hi! What brings you here today?"}}, 
    {10, "hi*", {"Hello! How can I help you?", "Hi there! Tell me what's on your mind.", "Hi! How are you doing today?"}}, 
    {10, "good morning*", {"Good morning! How are you feeling this morning?", "Good morning! What's on your mind today?"}}, 
    {10, "good afternoon*", {"Good afternoon! How has your day been so far?", "Good afternoon! What would you like to talk about?"}}, 
    {10, "good evening*", {"Good evening! How are you feeling tonight?", "Good evening! What's been on your mind today?"}}, 
    {10, "goodbye*", {"Goodbye! It was nice talking with you.", "Take care of yourself. Goodbye!"}}, 
    {10, "bye*", {"Goodbye! I hope our conversation was helpful.", "Take care! Feel free to come back anytime."}}, 
    {10, "see you*", {"See you later! Remember, I'm always here to listen."}}, 
     
    -- Personal information (priority 9) 
    {9, "my name is *", {"Hello %s! It's nice to meet you.", "Nice to meet you, %s. What brings you here today?", "Welcome %s! How are you feeling?"}}, 
    {9, "i'm * years old", {"What's it like being %s?", "How do you feel about being %s years old?", "Tell me about your life at %s."}}, 
    {9, "i am * years old", {"Age %s - what's that like for you?", "How does being %s affect how you see things?"}}, 
    {9, "i live in *", {"What's it like living in %s?", "How do you feel about %s?", "Tell me about life in %s."}}, 
    {9, "i work as *", {"How do you feel about being %s?", "What's it like working as %s?", "Do you enjoy being %s?"}}, 
    {9, "i am a *", {"Tell me more about being %s.", "How long have you been %s?", "What does being %s mean to you?"}}, 
     
    -- Feelings and emotions (priority 8) 
    {8, "i feel *", {"Tell me more about feeling %s.", "Why do you feel %s?", "How long have you been feeling %s?", "What makes you feel %s?"}}, 
    {8, "i am feeling *", {"Can you describe this feeling of %s more?", "What's causing you to feel %s?", "When did you start feeling %s?"}}, 
    {8, "i'm sad*", {"I'm sorry you're feeling sad. What's making you feel this way?", "Sadness can be difficult. What's troubling you?", "Tell me more about your sadness."}}, 
    {8, "i'm happy*", {"That's wonderful! What's making you happy?", "I'm glad you're feeling happy. What's going well?", "What's bringing you joy?"}}, 
    {8, "i'm angry*", {"What's making you angry?", "Anger can be powerful. What triggered it?", "Tell me more about your anger."}}, 
    {8, "i'm scared*", {"What are you afraid of?", "Fear can be overwhelming. What's scaring you?", "Tell me about your fears."}}, 
    {8, "i'm worried*", {"What's worrying you?", "What's on your mind that's causing worry?", "Tell me about your concerns."}}, 
    {8, "i'm lonely*", {"Loneliness can be painful. Tell me more.", "What makes you feel lonely?", "When do you feel most lonely?"}}, 
    {8, "i'm confused*", {"What's confusing you?", "Confusion can be frustrating. What's unclear?", "Tell me about what's puzzling you."}}, 
    {8, "i'm stressed*", {"What's causing you stress?", "Stress can be overwhelming. What's the source?", "Tell me about your stress."}}, 
    {8, "i'm depressed*", {"I'm sorry you're feeling depressed. What's been happening?", "Depression is serious. What's been going on?", "Tell me about your depression."}}, 
    {8, "i'm anxious*", {"What's making you anxious?", "Anxiety can be difficult. What triggers it?", "Tell me about your anxiety."}}, 
    {8, "i'm excited*", {"That's great! What's got you excited?", "What's happening that's exciting you?", "Tell me about your excitement."}}, 
     
    -- Thoughts and beliefs (priority 7) 
    {7, "i think *", {"What makes you think %s?", "Do you really think %s?", "Why do you believe %s?", "Tell me more about thinking %s."}}, 
    {7, "i believe *", {"What leads you to believe %s?", "How strongly do you believe %s?", "Why is believing %s important to you?"}}, 
    {7, "i know *", {"How do you know %s?", "What makes you so certain about %s?", "Tell me more about %s."}}, 
    {7, "i understand *", {"What helps you understand %s?", "How did you come to understand %s?", "Tell me about understanding %s."}}, 
    {7, "i realize *", {"When did you realize %s?", "What made you realize %s?", "How does realizing %s make you feel?"}}, 
    {7, "i wonder *", {"What makes you wonder about %s?", "Why do you wonder %s?", "Tell me more about wondering %s."}}, 
     
    -- Family relationships (priority 7) 
    {7, "my mother *", {"Tell me more about your mother.", "How do you feel about your mother?", "What is your relationship with your mother like?", "How does your mother make you feel?"}}, 
    {7, "my father *", {"Tell me more about your father.", "How does your father make you feel?", "What is your relationship with your father like?", "How do you get along with your father?"}}, 
    {7, "my parents *", {"Tell me about your parents.", "How do you feel about your parents?", "What role do your parents play in your life?"}}, 
    {7, "my family *", {"Tell me about your family.", "How important is your family to you?", "What is your family like?", "How does your family make you feel?"}}, 
    {7, "my brother *", {"Tell me about your brother.", "How do you and your brother get along?", "What's your relationship with your brother like?"}}, 
    {7, "my sister *", {"Tell me about your sister.", "How do you feel about your sister?", "What's your relationship with your sister like?"}}, 
     
    -- Social relationships (priority 7) 
    {7, "my friend *", {"Tell me about this friend.", "How do you feel about your friend?", "What does this friendship mean to you?", "How long have you been friends?"}}, 
    {7, "my friends *", {"Tell me about your friends.", "How important are your friends to you?", "What are your friendships like?"}}, 
    {7, "my boss *", {"Tell me about your boss.", "How do you feel about your boss?", "How do you get along with your boss?"}}, 
     
    -- Desires and goals (priority 6) 
    {6, "i want *", {"Why do you want %s?", "What would happen if you got %s?", "What does wanting %s mean to you?", "How important is %s to you?"}}, 
    {6, "i need *", {"Why do you need %s?", "What would happen if you didn't get %s?", "How important is %s to you?", "Tell me more about needing %s."}}, 
    {6, "i wish *", {"Tell me more about this wish.", "Why do you wish %s?", "What would it mean if %s came true?", "How long have you wished for %s?"}}, 
    {6, "i hope *", {"What makes you hope for %s?", "How important is this hope to you?", "What if %s doesn't happen?", "Tell me about your hopes."}}, 
    {6, "i love *", {"What do you love about %s?", "How does %s make you feel?", "Tell me more about loving %s."}}, 
    {6, "i hate *", {"What do you hate about %s?", "Why does %s make you feel that way?", "Tell me more about hating %s."}}, 
    {6, "i like *", {"What do you like about %s?", "How does %s make you feel?", "Tell me more about %s."}}, 
    {6, "i enjoy *", {"What do you enjoy about %s?", "How does %s make you feel?", "Tell me more about enjoying %s."}}, 
     
    -- Problems and difficulties (priority 8) 
    {8, "i have a problem*", {"What kind of problem is troubling you?", "Tell me about this problem.", "How does this problem make you feel?", "When did this problem start?"}}, 
    {8, "i can't *", {"What prevents you from %s?", "Why can't you %s?", "What would help you to %s?", "How does not being able to %s make you feel?"}}, 
    {8, "i don't *", {"Why don't you %s?", "What stops you from %s?", "How do you feel about not %s?", "What would it take for you to %s?"}}, 
    {8, "i won't *", {"Why won't you %s?", "What's stopping you from %s?", "How do you feel about not %s?"}}, 
    {8, "i'm afraid *", {"What are you afraid of?", "Tell me about your fear of %s.", "How does this fear affect you?", "When did you start being afraid of %s?"}}, 
    {8, "it's difficult*", {"What makes it difficult?", "How do you cope with the difficulty?", "Tell me more about this difficulty."}}, 
    {8, "it's hard*", {"What makes it hard?", "How do you deal with things being hard?", "Tell me about this challenge."}}, 
    {8, "it's impossible*", {"Nothing is impossible. What makes you think so?", "Why does it seem impossible?", "What would make it possible?"}}, 
    {8, "i'm stuck*", {"What's keeping you stuck?", "How does being stuck make you feel?", "What would help you get unstuck?"}}, 
     
    -- Past experiences (priority 6) 
    {6, "i remember *", {"What does remembering %s bring up for you?", "Why is this memory important?", "How does this memory make you feel?", "Tell me more about %s."}}, 
    {6, "when i was *", {"Tell me more about that time.", "How did that experience affect you?", "What was that like for you?", "How do you feel about that period?"}}, 
    {6, "i used to *", {"Why did you stop %s?", "How do you feel about no longer %s?", "What changed?", "Do you miss %s?"}}, 
     
    -- Work and programming (priority 6) 
    {6, "at work *", {"Tell me about your work.", "How do you feel about your job?", "What's your work situation like?"}}, 
    {6, "my job *", {"How do you feel about your job?", "Tell me about your work.", "What's your job like?"}}, 
    {6, "i code *", {"How do you feel about coding?", "Tell me about your programming.", "What do you like about coding?"}}, 
    {6, "i program *", {"How do you feel about programming?", "Tell me about your coding experience.", "What's programming like for you?"}}, 
    {6, "computer*", {"How do you feel about computers?", "Tell me about your experience with computers.", "What role do computers play in your life?"}}, 
     
    -- Questions about ELIZA (priority 5) 
    {5, "are you *", {"Why do you ask if I am %s?", "Does it matter if I am %s?", "What if I were %s?", "How would you feel if I were %s?"}}, 
    {5, "what are you*", {"Why do you ask?", "What do you think I am?", "Does it matter what I am?", "I'm here to listen to you."}}, 
    {5, "who are you*", {"I'm here to listen to you. Tell me about yourself.", "What's important is who you are. Tell me about yourself.", "I'm ELIZA. What about you?"}}, 
    {5, "do you *", {"Why do you ask if I %s?", "What if I do %s?", "How would that make you feel?"}}, 
    {5, "can you *", {"What do you think?", "Why do you ask?", "Does it matter if I can %s?"}}, 
     
    -- Responses to ELIZA (priority 4) 
    {4, "you are *", {"What makes you think I am %s?", "Does it please you to think I am %s?", "How does my being %s make you feel?"}}, 
    {4, "you * me", {"Why do you think I %s you?", "How does it feel when I %s you?", "What makes you think I %s you?"}}, 
     
    -- Common responses (priority 3) 
    {3, "yes*", {"You seem quite sure.", "I see.", "Can you elaborate on that?", "You sound certain. Tell me more."}}, 
    {3, "no*", {"Why not?", "Are you saying no just to be negative?", "You seem quite certain.", "Tell me more about that."}}, 
    {3, "maybe*", {"You don't seem very certain.", "Why are you unsure?", "What makes you hesitant?", "Tell me about your uncertainty."}}, 
    {3, "sometimes*", {"When do you feel that way?", "Tell me about those times.", "What makes the difference?"}}, 
    {3, "always*", {"Really, always?", "That's a strong statement. Tell me more.", "What makes you so certain?"}}, 
    {3, "never*", {"Never is a strong word. Tell me more.", "What makes you so certain?", "Really, never?"}}, 
    {3, "because *", {"Is that the real reason?", "What other reasons might there be?", "Does that reason seem adequate to you?", "Tell me more about %s."}}, 
    {3, "sorry*", {"Please don't apologize.", "What are you sorry about?", "No need for apologies.", "Apologies aren't necessary. Tell me more."}}, 
    {3, "thank you*", {"You're welcome.", "How does that make you feel?", "Tell me more."}}, 
     
    -- Default fallbacks with more variety (priority 1) 
    {1, "*", { 
        "Tell me more.",  
        "How does that make you feel?",  
        "What does that suggest to you?",  
        "Can you elaborate on that?",  
        "Why do you say that?",  
        "That's interesting. Please continue.",  
        "What comes to mind when you think about that?", 
        "I see. Go on.", 
        "Please tell me more about that.", 
        "How do you feel about that?", 
        "What are your thoughts on that?", 
        "Can you explain that further?", 
        "What's your perspective on that?", 
        "How does that affect you?", 
        "What's important about that to you?", 
        "Tell me what that means to you.", 
        "How long have you felt this way?", 
        "What would you like to explore about that?", 
        "What stands out to you about that?", 
        "How significant is that for you?" 
    }} 
} 
 
-- Utility functions 
function allocate_string_ex(sequence s) 
    atom ptr = allocate(length(s) + 1) 
    poke(ptr, s & 0) 
    return ptr 
end function 
 
function lower(sequence s) 
    sequence result = "" 
    for i = 1 to length(s) do 
        integer ch = s[i] 
        if ch >= 'A' and ch <= 'Z' then 
            result = append(result, ch + 32) 
        else 
            result = append(result, ch) 
        end if 
    end for 
    return result 
end function 
 
function rshift(atom value, integer bits) 
    atom divisor = 1 
    for i = 1 to bits do 
        divisor = divisor * 2 
    end for 
    return floor(value / divisor) 
end function 
 
function floor(atom x) 
    if x >= 0 then 
        return x - remainder(x, 1) 
    else 
        atom result = x - remainder(x, 1) 
        if remainder(x, 1) != 0 then 
            result = result - 1 
        end if 
        return result 
    end if 
end function 
 
function trim(sequence s) 
    integer start = 1, stop = length(s) 
    while start <= stop and find(s[start], " \t\n\r") do 
        start += 1 
    end while 
    while stop >= start and find(s[stop], " \t\n\r") do 
        stop -= 1 
    end while 
    if start > stop then 
        return "" 
    else 
        return s[start..stop] 
    end if 
end function 
 
function match_pattern(sequence input, sequence pattern) 
    sequence input_lower = lower(input) 
    sequence pattern_lower = lower(pattern) 
     
    if pattern_lower[length(pattern_lower)] = '*' then 
        sequence prefix = pattern_lower[1..length(pattern_lower)-1] 
        if length(input_lower) >= length(prefix) then 
            if equal(input_lower[1..length(prefix)], prefix) then 
                if length(input_lower) > length(prefix) then 
                    return {1, input[length(prefix)+1..length(input)]} 
                else 
                    return {1, ""} 
                end if 
            end if 
        end if 
    else 
        if equal(input_lower, pattern_lower) then 
            return {1, ""} 
        end if 
    end if 
    return {0, ""} 
end function 
 
function substitute_placeholder(sequence response, sequence replacement) 
    integer pos = find('%', response) 
    if pos and pos < length(response) and response[pos+1] = 's' then 
        return response[1..pos-1] & replacement & response[pos+2..length(response)] 
    end if 
    return response 
end function 
 
function eliza_respond(sequence input) 
    sequence trimmed_input = trim(input) 
    if length(trimmed_input) = 0 then 
        return "I'm listening. Please tell me what's on your mind." 
    end if 
     
    -- Sort patterns by priority (highest first) 
    sequence sorted_patterns = eliza_patterns 
    for i = 1 to length(sorted_patterns) - 1 do 
        for j = i + 1 to length(sorted_patterns) do 
            if sorted_patterns[i][1] < sorted_patterns[j][1] then 
                sequence temp = sorted_patterns[i] 
                sorted_patterns[i] = sorted_patterns[j] 
                sorted_patterns[j] = temp 
            end if 
        end for 
    end for 
     
    for i = 1 to length(sorted_patterns) do 
        sequence pattern = sorted_patterns[i][2] 
        sequence responses = sorted_patterns[i][3] 
         
        sequence match_result = match_pattern(trimmed_input, pattern) 
        if match_result[1] = 1 then 
            sequence response = responses[rand(length(responses))] 
            if find('%', response) then 
                response = substitute_placeholder(response, match_result[2]) 
            end if 
            return response 
        end if 
    end for 
     
    return "I'm not sure I understand. Can you tell me more?" 
end function 
 
procedure add_to_chat(sequence message) 
    chat_history = append(chat_history, message) 
     
    sequence display_text = "" 
    for i = 1 to length(chat_history) do 
        display_text &= chat_history[i] & "\r\n\r\n" 
    end for 
     
    atom c_text = allocate_string_ex(display_text) 
    atom result = c_func(SetWindowTextA, {hwnd_output, c_text}) 
    free(c_text) 
     
    -- Scroll to bottom 
    atom sel_result = c_func(SendMessageA, {hwnd_output, EM_SETSEL, 0, length(display_text)}) 
    atom scroll_result = c_func(SendMessageA, {hwnd_output, EM_SCROLLCARET, 0, 0}) 
end procedure 
 
procedure process_input() 
    atom buffer = allocate(1000) 
    atom len = c_func(GetWindowTextA, {hwnd_input, buffer, 1000}) 
    sequence user_input = peek_string(buffer) 
    free(buffer) 
     
    if length(trim(user_input)) > 0 then 
        add_to_chat("You: " & user_input) 
        sequence response = eliza_respond(user_input) 
        add_to_chat("ELIZA: " & response) 
        atom empty = allocate_string_ex("") 
        atom result = c_func(SetWindowTextA, {hwnd_input, empty}) 
        free(empty) 
    end if 
end procedure 
 
procedure resize_controls(atom client_width, atom client_height) 
    integer margin = 10 
    integer button_width = 90 
    integer button_height = 30 
    integer input_height = 25 
    integer spacing = 5 
     
    integer output_width = client_width - 2 * margin 
    integer output_height = client_height - input_height - 3 * margin - button_height 
    integer input_width = client_width - button_width - 3 * margin 
     
    atom move_result1 = c_func(MoveWindow, {hwnd_output, margin, margin,  
        output_width, output_height, 1}) 
     
    atom move_result2 = c_func(MoveWindow, {hwnd_input, margin,  
        output_height + 2 * margin, input_width, input_height, 1}) 
     
    atom move_result3 = c_func(MoveWindow, {hwnd_send,  
        input_width + 2 * margin, output_height + 2 * margin,  
        button_width, button_height, 1}) 
     
    atom move_result4 = c_func(MoveWindow, {hwnd_clear,  
        input_width + 2 * margin, output_height + 2 * margin + button_height + spacing,  
        button_width, button_height, 1}) 
end procedure 
 
function WindowProc(atom hwnd, atom msg, atom wparam, atom lparam) 
    if msg = WM_CREATE then 
        atom h_instance = c_func(GetModuleHandleA, {0}) 
         
        -- Create output text area 
        atom class_edit = allocate_string_ex("EDIT") 
        atom init_text = allocate_string_ex("ELIZA: Hello! I'm ELIZA. How are you feeling today?\r\n\r\n") 
         
        hwnd_output = c_func(CreateWindowExA, { 
            0, class_edit, init_text, 
            WS_CHILD + WS_VISIBLE + WS_BORDER + ES_MULTILINE + ES_READONLY + WS_VSCROLL, 
            10, 10, 560, 340, 
            hwnd, ID_EDIT_OUTPUT, h_instance, 0 
        }) 
         
        -- Create input text area (single line) 
        atom empty_text = allocate_string_ex("") 
        hwnd_input = c_func(CreateWindowExA, { 
            0, class_edit, empty_text, 
            WS_CHILD + WS_VISIBLE + WS_BORDER, 
            10, 360, 460, 25, 
            hwnd, ID_EDIT_INPUT, h_instance, 0 
        }) 
         
        -- Create Send button (default button) 
        atom class_button = allocate_string_ex("BUTTON") 
        atom text_send = allocate_string_ex("Send") 
         
        hwnd_send = c_func(CreateWindowExA, { 
            0, class_button, text_send, 
            WS_CHILD + WS_VISIBLE + BS_DEFPUSHBUTTON, 
            480, 360, 90, 30, 
            hwnd, ID_BUTTON_SEND, h_instance, 0 
        }) 
         
        -- Create Clear button 
        atom text_clear = allocate_string_ex("Clear") 
        hwnd_clear = c_func(CreateWindowExA, { 
            0, class_button, text_clear, 
            WS_CHILD + WS_VISIBLE + BS_PUSHBUTTON, 
            480, 395, 90, 30, 
            hwnd, ID_BUTTON_CLEAR, h_instance, 0 
        }) 
         
        -- Free allocated strings 
        free(class_edit) 
        free(init_text) 
        free(empty_text) 
        free(class_button) 
        free(text_send) 
        free(text_clear) 
         
        -- Initialize chat 
        chat_history = {"ELIZA: Hello! I'm ELIZA. How are you feeling today?"} 
        return 0 
         
    elsif msg = WM_SIZE then 
        integer client_width = and_bits(lparam, #FFFF) 
        integer client_height = and_bits(rshift(lparam, 16), #FFFF) 
        resize_controls(client_width, client_height) 
        return 0 
         
    elsif msg = WM_COMMAND then 
        atom control_id = and_bits(wparam, #FFFF) 
         
        if control_id = ID_BUTTON_SEND or control_id = ID_ACCEL_ENTER then 
            -- Handle both button click and Enter key accelerator 
            atom focused_window = c_func(GetFocus, {}) 
            if control_id = ID_ACCEL_ENTER then 
                -- Only process Enter if input field has focus 
                if focused_window = hwnd_input then 
                    process_input() 
                end if 
            else 
                -- Always process button click 
                process_input() 
            end if 
        elsif control_id = ID_BUTTON_CLEAR then 
            chat_history = {"ELIZA: Hello! I'm ELIZA. How are you feeling today?"} 
            add_to_chat("") 
        end if 
        return 0 
         
    elsif msg = WM_CLOSE then 
        c_proc(PostQuitMessage, {0}) 
        return 0 
    end if 
     
    return c_func(DefWindowProcA, {hwnd, msg, wparam, lparam}) 
end function 
 
procedure main() 
    atom h_instance = c_func(GetModuleHandleA, {0}) 
     
    -- Create accelerator table for Enter key 
    atom accel_table = allocate(8)  -- ACCEL structure size (8 bytes) 
    poke(accel_table, FVIRTKEY)     -- fVirt 
    poke(accel_table + 1, 0)        -- padding 
    poke2(accel_table + 2, VK_RETURN)  -- key 
    poke2(accel_table + 4, ID_ACCEL_ENTER)  -- cmd 
    poke2(accel_table + 6, 0)       -- padding 
     
    h_accel_table = c_func(CreateAcceleratorTableA, {accel_table, 1}) 
     
    -- Register window class 
    sequence class_name = "ElizaChatbot" 
    atom wndclass = allocate(40) 
    atom class_name_ptr = allocate_string_ex(class_name) 
     
    poke4(wndclass, 0) 
    poke4(wndclass + 4, call_back(routine_id("WindowProc"))) 
    poke4(wndclass + 8, 0) 
    poke4(wndclass + 12, 0) 
    poke4(wndclass + 16, h_instance) 
    poke4(wndclass + 20, 0) 
    poke4(wndclass + 24, c_func(LoadCursorA, {0, 32512})) 
    poke4(wndclass + 28, 6) 
    poke4(wndclass + 32, 0) 
    poke4(wndclass + 36, class_name_ptr) 
     
    if c_func(RegisterClassA, {wndclass}) = 0 then 
        puts(1, "Failed to register window class\n") 
        return 
    end if 
     
    -- Create main window 
    atom window_title = allocate_string_ex("ELIZA Chatbot - Euphoria") 
     
    hwnd_main = c_func(CreateWindowExA, { 
        0, class_name_ptr, window_title, 
        WS_OVERLAPPEDWINDOW + WS_VISIBLE, 
        100, 100, 600, 470, 
        0, 0, h_instance, 0 
    }) 
     
    if hwnd_main = 0 then 
        puts(1, "Failed to create window\n") 
        return 
    end if 
     
    atom show_result = c_func(ShowWindow, {hwnd_main, SW_SHOWNORMAL}) 
    atom update_result = c_func(UpdateWindow, {hwnd_main}) 
     
    -- Message loop with accelerator support 
    atom msg = allocate(28) 
    while 1 do 
        atom result = c_func(GetMessageA, {msg, 0, 0, 0}) 
        if result = 0 or result = -1 then 
            exit 
        end if 
         
        -- Try to translate accelerator first 
        if h_accel_table != 0 then 
            atom accel_result = c_func(TranslateAcceleratorA, {hwnd_main, h_accel_table, msg}) 
            if accel_result != 0 then 
                -- Accelerator was processed, skip normal message processing 
            else 
                atom translate_result = c_func(TranslateMessage, {msg}) 
                atom dispatch_result = c_func(DispatchMessageA, {msg}) 
            end if 
        else 
            atom translate_result = c_func(TranslateMessage, {msg}) 
            atom dispatch_result = c_func(DispatchMessageA, {msg}) 
        end if 
    end while 
     
    -- Cleanup 
    free(accel_table) 
    free(wndclass) 
    free(class_name_ptr) 
    free(window_title) 
    free(msg) 
end procedure 
 
-- Start the application 
main() 
new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu