hi World Clock GUI (win32lib) program

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

Hi all, it's been a while since my last post - so I downloaded and installed Euphoria again (this time I've switched back to my Windows 11 OS) and also win32lib, and I decided to try and code "something useful" It's a GUI app for Windows using Win32Lib in Euphoria. It's a world clock app that shows the local time. You can add cities from a list of 250 cities around the world. It will show you the time there as well as the timezone - you select a city and click add city. It saves it in an ini file for next time you run the program and you can remove a city by clicking it (fast) and pressing del button or just press remove city and it will ask you if to remove the last added town from the list... worldclock.exw

-- World Clock Application in Euphoria using win32lib 
-- Port from C/Windows API version 
 
include win32lib.ew 
include std/io.e 
include std/get.e 
include std/datetime.e 
 
-- Constants 
constant MAX_CITIES = 250 
constant MAX_SELECTED_CITIES = 20 
constant INI_FILE_NAME = "worldclock.ini" 
 
-- Control IDs 
constant ID_COMBO_CITIES = 1001 
constant ID_BUTTON_ADD = 1002 
constant ID_LISTBOX_CLOCKS = 1003 
constant ID_TIMER = 1004 
constant ID_BUTTON_REMOVE = 1005 
 
-- Window and control variables 
atom hMainWnd, hCombo, hButton, hListBox, hRemoveButton 
integer selected_count, city_count 
 
-- City structure: {name, timezone, utc_offset_hours, utc_offset_minutes} 
sequence cities, selected_cities 
 
-- Initialize cities database 
procedure init_cities() 
    cities = { 
        -- North America 
        {"New York", "EST/EDT", -5, 0}, 
        {"Los Angeles", "PST/PDT", -8, 0}, 
        {"Chicago", "CST/CDT", -6, 0}, 
        {"Denver", "MST/MDT", -7, 0}, 
        {"Miami", "EST/EDT", -5, 0}, 
        {"Seattle", "PST/PDT", -8, 0}, 
        {"Toronto", "EST/EDT", -5, 0}, 
        {"Vancouver", "PST/PDT", -8, 0}, 
        {"Montreal", "EST/EDT", -5, 0}, 
        {"Mexico City", "CST", -6, 0}, 
        {"Anchorage", "AKST/AKDT", -9, 0}, 
        {"Honolulu", "HST", -10, 0}, 
        {"Phoenix", "MST", -7, 0}, 
        {"Las Vegas", "PST/PDT", -8, 0}, 
        {"Atlanta", "EST/EDT", -5, 0}, 
        {"Boston", "EST/EDT", -5, 0}, 
        {"Dallas", "CST/CDT", -6, 0}, 
        {"Houston", "CST/CDT", -6, 0}, 
        {"Philadelphia", "EST/EDT", -5, 0}, 
        {"San Francisco", "PST/PDT", -8, 0}, 
        {"Washington DC", "EST/EDT", -5, 0}, 
        {"Detroit", "EST/EDT", -5, 0}, 
        {"Minneapolis", "CST/CDT", -6, 0}, 
        {"New Orleans", "CST/CDT", -6, 0}, 
        {"Portland", "PST/PDT", -8, 0}, 
        {"San Diego", "PST/PDT", -8, 0}, 
        {"Orlando", "EST/EDT", -5, 0}, 
        {"Nashville", "CST/CDT", -6, 0}, 
        {"Memphis", "CST/CDT", -6, 0}, 
        {"Cleveland", "EST/EDT", -5, 0}, 
         
        -- Europe 
        {"London", "GMT/BST", 0, 0}, 
        {"Paris", "CET/CEST", 1, 0}, 
        {"Berlin", "CET/CEST", 1, 0}, 
        {"Rome", "CET/CEST", 1, 0}, 
        {"Madrid", "CET/CEST", 1, 0}, 
        {"Amsterdam", "CET/CEST", 1, 0}, 
        {"Vienna", "CET/CEST", 1, 0}, 
        {"Brussels", "CET/CEST", 1, 0}, 
        {"Zurich", "CET/CEST", 1, 0}, 
        {"Munich", "CET/CEST", 1, 0}, 
        {"Frankfurt", "CET/CEST", 1, 0}, 
        {"Milan", "CET/CEST", 1, 0}, 
        {"Barcelona", "CET/CEST", 1, 0}, 
        {"Copenhagen", "CET/CEST", 1, 0}, 
        {"Stockholm", "CET/CEST", 1, 0}, 
        {"Oslo", "CET/CEST", 1, 0}, 
        {"Helsinki", "EET/EEST", 2, 0}, 
        {"Warsaw", "CET/CEST", 1, 0}, 
        {"Prague", "CET/CEST", 1, 0}, 
        {"Budapest", "CET/CEST", 1, 0}, 
        {"Athens", "EET/EEST", 2, 0}, 
        {"Lisbon", "WET/WEST", 0, 0}, 
        {"Dublin", "GMT/IST", 0, 0}, 
        {"Edinburgh", "GMT/BST", 0, 0}, 
        {"Moscow", "MSK", 3, 0}, 
        {"Istanbul", "TRT", 3, 0}, 
        {"Kiev", "EET/EEST", 2, 0}, 
        {"St Petersburg", "MSK", 3, 0}, 
        {"Reykjavik", "GMT", 0, 0}, 
        {"Luxembourg", "CET/CEST", 1, 0}, 
         
        -- Asia 
        {"Tokyo", "JST", 9, 0}, 
        {"Beijing", "CST", 8, 0}, 
        {"Shanghai", "CST", 8, 0}, 
        {"Hong Kong", "HKT", 8, 0}, 
        {"Singapore", "SGT", 8, 0}, 
        {"Seoul", "KST", 9, 0}, 
        {"Mumbai", "IST", 5, 30}, 
        {"Delhi", "IST", 5, 30}, 
        {"Bangalore", "IST", 5, 30}, 
        {"Chennai", "IST", 5, 30}, 
        {"Kolkata", "IST", 5, 30}, 
        {"Bangkok", "ICT", 7, 0}, 
        {"Jakarta", "WIB", 7, 0}, 
        {"Manila", "PHT", 8, 0}, 
        {"Kuala Lumpur", "MYT", 8, 0}, 
        {"Ho Chi Minh City", "ICT", 7, 0}, 
        {"Taipei", "CST", 8, 0}, 
        {"Dhaka", "BST", 6, 0}, 
        {"Karachi", "PKT", 5, 0}, 
        {"Lahore", "PKT", 5, 0}, 
        {"Islamabad", "PKT", 5, 0}, 
        {"Kabul", "AFT", 4, 30}, 
        {"Tehran", "IRST", 3, 30}, 
        {"Baghdad", "AST", 3, 0}, 
        {"Riyadh", "AST", 3, 0}, 
        {"Dubai", "GST", 4, 0}, 
        {"Kuwait City", "AST", 3, 0}, 
        {"Doha", "AST", 3, 0}, 
        {"Abu Dhabi", "GST", 4, 0}, 
        {"Muscat", "GST", 4, 0}, 
        {"Yerevan", "AMT", 4, 0}, 
        {"Baku", "AZT", 4, 0}, 
        {"Tbilisi", "GET", 4, 0}, 
        {"Almaty", "ALMT", 6, 0}, 
        {"Tashkent", "UZT", 5, 0}, 
        {"Bishkek", "KGT", 6, 0}, 
        {"Dushanbe", "TJT", 5, 0}, 
        {"Ashgabat", "TMT", 5, 0}, 
        {"Ulaanbaatar", "ULAT", 8, 0}, 
        {"Colombo", "SLST", 5, 30}, 
         
        -- Africa 
        {"Cairo", "EET", 2, 0}, 
        {"Lagos", "WAT", 1, 0}, 
        {"Casablanca", "WET", 0, 0}, 
        {"Johannesburg", "SAST", 2, 0}, 
        {"Cape Town", "SAST", 2, 0}, 
        {"Nairobi", "EAT", 3, 0}, 
        {"Addis Ababa", "EAT", 3, 0}, 
        {"Dar es Salaam", "EAT", 3, 0}, 
        {"Kampala", "EAT", 3, 0}, 
        {"Kigali", "CAT", 2, 0}, 
        {"Accra", "GMT", 0, 0}, 
        {"Abidjan", "GMT", 0, 0}, 
        {"Dakar", "GMT", 0, 0}, 
        {"Tunis", "CET", 1, 0}, 
        {"Algiers", "CET", 1, 0}, 
        {"Tripoli", "EET", 2, 0}, 
        {"Khartoum", "CAT", 2, 0}, 
        {"Kinshasa", "WAT", 1, 0}, 
        {"Luanda", "WAT", 1, 0}, 
        {"Maputo", "CAT", 2, 0}, 
        {"Harare", "CAT", 2, 0}, 
        {"Lusaka", "CAT", 2, 0}, 
        {"Gaborone", "CAT", 2, 0}, 
        {"Windhoek", "CAT", 2, 0}, 
        {"Antananarivo", "EAT", 3, 0}, 
        {"Port Louis", "MUT", 4, 0}, 
        {"Rabat", "WET", 0, 0}, 
        {"Alexandria", "EET", 2, 0}, 
        {"Durban", "SAST", 2, 0}, 
        {"Pretoria", "SAST", 2, 0}, 
         
        -- Oceania 
        {"Sydney", "AEST/AEDT", 10, 0}, 
        {"Melbourne", "AEST/AEDT", 10, 0}, 
        {"Brisbane", "AEST", 10, 0}, 
        {"Perth", "AWST", 8, 0}, 
        {"Adelaide", "ACST/ACDT", 9, 30}, 
        {"Auckland", "NZST/NZDT", 12, 0}, 
        {"Wellington", "NZST/NZDT", 12, 0}, 
        {"Christchurch", "NZST/NZDT", 12, 0}, 
        {"Canberra", "AEST/AEDT", 10, 0}, 
        {"Darwin", "ACST", 9, 30}, 
        {"Hobart", "AEST/AEDT", 10, 0}, 
        {"Gold Coast", "AEST", 10, 0}, 
        {"Cairns", "AEST", 10, 0}, 
        {"Fiji", "FJT", 12, 0}, 
        {"Samoa", "WSST", 13, 0}, 
        {"Tonga", "TOT", 13, 0}, 
        {"Vanuatu", "VUT", 11, 0}, 
        {"Papua New Guinea", "PGT", 10, 0}, 
        {"New Caledonia", "NCT", 11, 0}, 
        {"Solomon Islands", "SBT", 11, 0}, 
         
        -- South America 
        {"Sao Paulo", "BRT", -3, 0}, 
        {"Rio de Janeiro", "BRT", -3, 0}, 
        {"Buenos Aires", "ART", -3, 0}, 
        {"Lima", "PET", -5, 0}, 
        {"Bogota", "COT", -5, 0}, 
        {"Santiago", "CLT", -4, 0}, 
        {"Caracas", "VET", -4, 0}, 
        {"Quito", "ECT", -5, 0}, 
        {"La Paz", "BOT", -4, 0}, 
        {"Asuncion", "PYT", -3, 0}, 
        {"Montevideo", "UYT", -3, 0}, 
        {"Georgetown", "GYT", -4, 0}, 
        {"Paramaribo", "SRT", -3, 0}, 
        {"Cayenne", "GFT", -3, 0}, 
        {"Brasilia", "BRT", -3, 0}, 
        {"Salvador", "BRT", -3, 0}, 
        {"Fortaleza", "BRT", -3, 0}, 
        {"Recife", "BRT", -3, 0}, 
        {"Belo Horizonte", "BRT", -3, 0}, 
        {"Porto Alegre", "BRT", -3, 0}, 
        {"Manaus", "AMT", -4, 0}, 
        {"Curitiba", "BRT", -3, 0}, 
        {"Goiania", "BRT", -3, 0}, 
        {"Belem", "BRT", -3, 0}, 
        {"Medellin", "COT", -5, 0}, 
        {"Cali", "COT", -5, 0}, 
        {"Barranquilla", "COT", -5, 0}, 
        {"Cordoba", "ART", -3, 0}, 
        {"Rosario", "ART", -3, 0}, 
        {"Mendoza", "ART", -3, 0}, 
         
        -- Central America & Caribbean 
        {"Guatemala City", "CST", -6, 0}, 
        {"San Jose", "CST", -6, 0}, 
        {"Panama City", "EST", -5, 0}, 
        {"Managua", "CST", -6, 0}, 
        {"Tegucigalpa", "CST", -6, 0}, 
        {"San Salvador", "CST", -6, 0}, 
        {"Belize City", "CST", -6, 0}, 
        {"Kingston", "EST", -5, 0}, 
        {"Havana", "CST/CDT", -5, 0}, 
        {"Santo Domingo", "AST", -4, 0}, 
        {"Port-au-Prince", "EST/EDT", -5, 0}, 
        {"San Juan", "AST", -4, 0}, 
        {"Bridgetown", "AST", -4, 0}, 
        {"Port of Spain", "AST", -4, 0}, 
        {"Nassau", "EST/EDT", -5, 0}, 
        {"George Town", "EST", -5, 0}, 
        {"Hamilton", "AST/ADT", -4, 0}, 
        {"Road Town", "AST", -4, 0}, 
        {"Charlotte Amalie", "AST", -4, 0}, 
        {"Willemstad", "AST", -4, 0}, 
         
        -- Additional Asia-Pacific 
        {"Kathmandu", "NPT", 5, 45}, 
        {"Thimphu", "BTT", 6, 0}, 
        {"Yangon", "MMT", 6, 30}, 
        {"Phnom Penh", "ICT", 7, 0}, 
        {"Vientiane", "ICT", 7, 0}, 
        {"Bandar Seri Begawan", "BNT", 8, 0}, 
        {"Dili", "TLT", 9, 0}, 
        {"Male", "MVT", 5, 0}, 
        {"Vladivostok", "VLAT", 10, 0}, 
        {"Irkutsk", "IRKT", 8, 0}, 
        {"Novosibirsk", "NOVT", 7, 0}, 
        {"Yekaterinburg", "YEKT", 5, 0}, 
        {"Omsk", "OMST", 6, 0}, 
        {"Krasnoyarsk", "KRAT", 7, 0}, 
        {"Yakutsk", "YAKT", 9, 0}, 
        {"Magadan", "MAGT", 11, 0}, 
        {"Petropavlovsk", "PETT", 12, 0}, 
        {"Anadyr", "ANAT", 12, 0}, 
        {"Pyongyang", "KST", 9, 0}, 
        {"Osaka", "JST", 9, 0}, 
        {"Kyoto", "JST", 9, 0}, 
        {"Yokohama", "JST", 9, 0}, 
        {"Nagoya", "JST", 9, 0}, 
        {"Sapporo", "JST", 9, 0}, 
        {"Fukuoka", "JST", 9, 0}, 
        {"Busan", "KST", 9, 0}, 
        {"Incheon", "KST", 9, 0}, 
        {"Daegu", "KST", 9, 0}, 
        {"Daejeon", "KST", 9, 0}, 
        {"Gwangju", "KST", 9, 0}, 
        {"Chengdu", "CST", 8, 0}, 
        {"Guangzhou", "CST", 8, 0}, 
        {"Shenzhen", "CST", 8, 0}, 
        {"Tianjin", "CST", 8, 0}, 
        {"Wuhan", "CST", 8, 0}, 
        {"Xi'an", "CST", 8, 0}, 
        {"Nanjing", "CST", 8, 0}, 
        {"Chongqing", "CST", 8, 0}, 
        {"Hangzhou", "CST", 8, 0}, 
        {"Qingdao", "CST", 8, 0}, 
        {"Macau", "CST", 8, 0}, 
        {"Jerusalem", "IST", 2, 0}, 
        {"Tel Aviv", "IST", 2, 0}, 
        {"Haifa", "IST", 2, 0}, 
        {"Amman", "EET/EEST", 2, 0}, 
        {"Beirut", "EET/EEST", 2, 0}, 
        {"Damascus", "EET/EEST", 2, 0}, 
        {"Nicosia", "EET/EEST", 2, 0}, 
        {"Valletta", "CET/CEST", 1, 0}, 
        {"Monaco", "CET/CEST", 1, 0} 
    } 
     
    city_count = length(cities) 
    selected_cities = {} 
    selected_count = 0 
end procedure 
 
-- Get current date/time as sequence {year, month, day, hour, minute, second} 
function get_current_datetime() 
    sequence dt = now() 
    -- now() returns {year, month, day, hour, minute, second, day_of_week, day_of_year} 
    -- We only need the first 6 elements 
    return dt[1..6] 
end function 
 
-- Calculate time for a city based on UTC offset 
function get_city_time(sequence city) 
    sequence local_time = get_current_datetime() 
    atom utc_offset_hours = city[3] 
    atom utc_offset_minutes = city[4] 
     
    -- Get local time components 
    atom year = local_time[1] 
    atom month = local_time[2]  
    atom day = local_time[3] 
    atom hour = local_time[4] 
    atom minute = local_time[5] 
    atom second = local_time[6] 
     
    -- Add the UTC offset to get city time 
    -- This is simplified - doesn't account for local timezone or DST 
    hour += utc_offset_hours 
    minute += utc_offset_minutes 
     
    -- Handle minute overflow 
    if minute >= 60 then 
        minute -= 60 
        hour += 1 
    elsif minute < 0 then 
        minute += 60 
        hour -= 1 
    end if 
     
    -- Handle hour overflow/underflow 
    if hour >= 24 then 
        hour -= 24 
    elsif hour < 0 then 
        hour += 24 
    end if 
     
    return {hour, minute, second} 
end function 
 
-- Format time difference 
function format_time_difference(atom diff_minutes) 
    atom hours, minutes 
    sequence buffer 
     
    hours = floor(abs(diff_minutes) / 60) 
    minutes = remainder(abs(diff_minutes), 60) 
     
    if diff_minutes = 0 then 
        buffer = "Same time" 
    elsif diff_minutes > 0 then 
        if minutes = 0 then 
            buffer = sprintf("+%d hours ahead", hours) 
        else 
            buffer = sprintf("+%d:%02d hours ahead", {hours, minutes}) 
        end if 
    else 
        if minutes = 0 then 
            buffer = sprintf("-%d hours behind", hours) 
        else 
            buffer = sprintf("-%d:%02d hours behind", {hours, minutes}) 
        end if 
    end if 
     
    return buffer 
end function 
 
-- Calculate time difference between local and city time 
function calculate_time_difference(sequence city) 
    -- Simplified calculation - just return the UTC offset difference 
    return (city[3] * 60 + city[4]) 
end function 
 
-- Update the clock display 
procedure update_clocks() 
    sequence local_time, city_time, display_text, diff_str 
    atom diff 
     
    -- Clear the listbox properly 
    while getCount(hListBox) > 0 do 
        deleteItem(hListBox, 1) 
    end while 
     
    -- Add local time 
    local_time = get_current_datetime() 
    display_text = sprintf("LOCAL TIME: %02d:%02d:%02d",  
                          {local_time[4], local_time[5], local_time[6]}) 
    addItem(hListBox, display_text) 
    addItem(hListBox, "") 
     
    -- Add selected cities 
    for i = 1 to selected_count do 
        city_time = get_city_time(selected_cities[i]) 
        diff = calculate_time_difference(selected_cities[i]) 
        diff_str = format_time_difference(diff) 
         
        display_text = sprintf("%s (%s): %02d:%02d:%02d - %s", 
                              {selected_cities[i][1], selected_cities[i][2], 
                               city_time[1], city_time[2], city_time[3], diff_str}) 
         
        addItem(hListBox, display_text) 
    end for 
end procedure 
 
-- Save selected cities to INI file 
procedure save_selected_cities() 
    integer file_handle 
    sequence content 
     
    file_handle = open(INI_FILE_NAME, "w") 
    if file_handle = -1 then 
        return 
    end if 
     
    printf(file_handle, "[SelectedCities]\n") 
    printf(file_handle, "Count=%d\n", selected_count) 
     
    for i = 1 to selected_count do 
        printf(file_handle, "City%d=%s\n", {i-1, selected_cities[i][1]}) 
    end for 
     
    close(file_handle) 
end procedure 
 
-- Load selected cities from INI file 
procedure load_selected_cities() 
    integer file_handle 
    sequence file_content, lines 
    object temp_line 
     
    -- Initialize 
    selected_cities = {} 
    selected_count = 0 
     
    -- Try to open file 
    file_handle = open(INI_FILE_NAME, "r") 
    if file_handle = -1 then 
        -- File doesn't exist, that's OK 
        return 
    end if 
     
    -- Read entire file 
    file_content = "" 
    while 1 do 
        temp_line = gets(file_handle) 
        if atom(temp_line) then 
            exit 
        end if 
        file_content &= temp_line 
    end while 
    close(file_handle) 
     
    -- If file is empty, return 
    if length(file_content) = 0 then 
        return 
    end if 
     
    -- Split into lines 
    lines = {} 
    sequence current_line = "" 
    for i = 1 to length(file_content) do 
        if file_content[i] = '\n' then 
            if length(current_line) > 0 then 
                lines = append(lines, current_line) 
            end if 
            current_line = "" 
        elsif file_content[i] != '\r' then 
            current_line &= file_content[i] 
        end if 
    end for 
    -- Add last line if it doesn't end with newline 
    if length(current_line) > 0 then 
        lines = append(lines, current_line) 
    end if 
     
    -- Process each line 
    for i = 1 to length(lines) do 
        sequence line = lines[i] 
         
        -- Skip empty lines and section headers 
        if length(line) = 0 or line[1] = '[' then 
            -- Skip this line 
        elsif length(line) > 5 and equal(line[1..4], "City") then 
            -- Look for equals sign 
            integer eq_pos = 0 
            for j = 5 to length(line) do 
                if line[j] = '=' then 
                    eq_pos = j 
                    exit 
                end if 
            end for 
             
            -- Extract city name if equals found 
            if eq_pos > 0 and eq_pos < length(line) then 
                sequence city_name = line[eq_pos+1..length(line)] 
                 
                -- Find city in database 
                for k = 1 to city_count do 
                    if equal(cities[k][1], city_name) then 
                        if selected_count < MAX_SELECTED_CITIES then 
                            selected_count += 1 
                            selected_cities = append(selected_cities, cities[k]) 
                        end if 
                        exit 
                    end if 
                end for 
            end if 
        end if 
    end for 
end procedure 
 
-- Add selected city 
procedure add_city() 
    integer sel 
    sequence city_name 
     
    if selected_count >= MAX_SELECTED_CITIES then 
        {} = message_box("Maximum number of cities reached!", "Warning", MB_OK) 
        return 
    end if 
     
    sel = getIndex(hCombo) 
    if sel = 0 then 
        {} = message_box("Please select a city!", "Warning", MB_OK) 
        return 
    end if 
     
    -- Check if city already added 
    city_name = cities[sel][1] 
    for i = 1 to selected_count do 
        if equal(selected_cities[i][1], city_name) then 
            {} = message_box("City already added!", "Warning", MB_OK) 
            return 
        end if 
    end for 
     
    -- Add the city 
    selected_count += 1 
    selected_cities = append(selected_cities, cities[sel]) 
     
    -- Save to INI file 
    save_selected_cities() 
     
    -- Update display 
    update_clocks() 
end procedure 
 
-- Remove selected city 
procedure remove_selected_city() 
    integer sel, city_index 
    sequence message_text 
     
    -- Get the selection 
    sel = getIndex(hListBox) 
     
    -- Debug: print the selection 
    printf(1, "Selected index: %d\n", sel) 
     
    if sel = 0 or sel = -1 then 
        -- No selection, we'll handle this in the button handler 
        return 
    end if 
     
    if sel <= 2 then -- Skip local time and empty line 
        {} = message_box("Cannot remove local time entry!\n\nPlease select a city (not the local time).", "Information", MB_OK) 
        return 
    end if 
     
    city_index = sel - 2 
    printf(1, "City index: %d, selected_count: %d\n", {city_index, selected_count}) 
     
    if city_index >= 1 and city_index <= selected_count then 
        message_text = sprintf("Remove %s from the list?", {selected_cities[city_index][1]}) 
         
        if message_box(message_text, "Confirm Removal", MB_YESNO) = IDYES then 
            -- Remove city from array 
            if city_index = 1 and selected_count = 1 then 
                -- Only one city, make array empty 
                selected_cities = {} 
            elsif city_index = selected_count then 
                -- Last city, remove it 
                selected_cities = selected_cities[1..selected_count-1] 
            else 
                -- City in middle, join before and after 
                selected_cities = selected_cities[1..city_index-1] &  
                                 selected_cities[city_index+1..selected_count] 
            end if 
            selected_count -= 1 
             
            -- Save the updated list 
            save_selected_cities() 
             
            -- Update display 
            update_clocks() 
             
            printf(1, "City removed successfully. New count: %d\n", selected_count) 
        end if 
    else 
        printf(1, "Invalid city index: %d\n", city_index) 
        {} = message_box("Invalid selection!", "Error", MB_OK) 
    end if 
end procedure 
 
-- Timer procedure 
procedure timer_handler(integer id, integer event, sequence params) 
    if event = w32HTimer then 
        update_clocks() 
    end if 
end procedure 
 
-- Alternative: Remove the last added city 
procedure remove_last_city() 
    sequence message_text 
     
    if selected_count = 0 then 
        {} = message_box("No cities to remove!", "Information", MB_OK) 
        return 
    end if 
     
    message_text = sprintf("Remove %s (last city) from the list?", {selected_cities[selected_count][1]}) 
     
    if message_box(message_text, "Confirm Removal", MB_YESNO) = IDYES then 
        selected_count -= 1 
        if selected_count = 0 then 
            selected_cities = {} 
        else 
            selected_cities = selected_cities[1..selected_count] 
        end if 
         
        -- Save the updated list 
        save_selected_cities() 
         
        -- Update display 
        update_clocks() 
         
        printf(1, "Last city removed successfully. New count: %d\n", selected_count) 
    end if 
end procedure 
 
-- Button handlers 
procedure button_add_handler(integer id, integer event, sequence params) 
    if event = w32HClick then 
        add_city() 
    end if 
end procedure 
 
procedure button_remove_handler(integer id, integer event, sequence params) 
    if event = w32HClick then 
        -- Try normal remove first 
        remove_selected_city() 
        -- If that didn't work (selection = 0), offer to remove last city 
        if getIndex(hListBox) = 0 and selected_count > 0 then 
            remove_last_city() 
        end if 
    end if 
end procedure 
 
-- Event handler for main window 
procedure main_window_handler(integer id, integer event, sequence params) 
    if event = w32HResize then 
        -- Handle window resizing 
        sequence rect = getClientRect(hMainWnd) 
        integer width = rect[3] - rect[1] 
        integer height = rect[4] - rect[2] 
         
        -- Resize controls 
        setRect(hCombo, 10, 10, width - 200, 25, 1) 
        setRect(hButton, width - 180, 10, 80, 25, 1) 
        setRect(hRemoveButton, width - 90, 10, 80, 25, 1) 
        setRect(hListBox, 10, 50, width - 20, height - 60, 1) 
    end if 
end procedure 
 
-- Listbox event handler for Delete key 
procedure listbox_handler(integer id, integer event, sequence params) 
    if event = w32HKeyDown and params[1] = VK_DELETE then 
        remove_selected_city() 
    end if 
end procedure 
 
-- Main program 
procedure main() 
    -- Initialize cities database 
    init_cities() 
     
    -- Create main window 
    hMainWnd = create(Window, "World Clock Application", 0, 50, 50, 600, 500,  
                     {WS_OVERLAPPEDWINDOW, WS_VISIBLE}) 
    setHandler(hMainWnd, w32HActivate, routine_id("main_window_handler")) 
    setHandler(hMainWnd, w32HResize, routine_id("main_window_handler")) 
     
    -- Create combo box 
    hCombo = create(ComboBox, "", hMainWnd, 10, 10, 350, 200, CBS_DROPDOWNLIST) 
     
    -- Populate combo box with cities 
    for i = 1 to city_count do 
        addItem(hCombo, cities[i][1]) 
    end for 
     
    -- Create buttons 
    hButton = create(PushButton, "Add City", hMainWnd, 370, 10, 80, 25, 0) 
    setHandler(hButton, w32HClick, routine_id("button_add_handler")) 
     
    hRemoveButton = create(PushButton, "Remove", hMainWnd, 460, 10, 80, 25, 0) 
    setHandler(hRemoveButton, w32HClick, routine_id("button_remove_handler")) 
     
    -- Create listbox - make sure it's visible 
    hListBox = create(ListBox, "", hMainWnd, 10, 45, 560, 400, 0) 
    setHandler(hListBox, w32HKeyDown, routine_id("listbox_handler")) 
     
    -- Load previously selected cities 
    load_selected_cities() 
     
    -- Set up timer for updating clocks every second 
    setTimer(hMainWnd, ID_TIMER, 1000) 
    setHandler(hMainWnd, w32HTimer, routine_id("timer_handler")) 
     
    -- Initial clock update 
    update_clocks() 
     
    -- Debug: Print what we have loaded 
    printf(1, "Selected cities count: %d\n", selected_count) 
    for i = 1 to selected_count do 
        printf(1, "City %d: %s\n", {i, selected_cities[i][1]}) 
    end for 
     
    -- Force a window refresh 
    repaintWindow(hMainWnd) 
     
    -- Start the message loop 
    WinMain(hMainWnd, Normal) 
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