// GuiSimple.cpp (730 lines) // // Coded by: Joseph Bertolami // Email: jbertola@uci.edu // // ICS 175A, Winter 2004 // // Project: Motif detection in yeast // Purpose: Handles application to Win32 interface including all aspects of the GUI #include "stdafx.h" #include "GuiSimple.h" #include "Commdlg.h" #include "DTable.h" #include "SequenceFinder.h" #include #include #include #include #include #pragma comment(lib, "shell32.lib") #pragma comment(lib, "comctl32.lib") HWND MainWnd = NULL; #define MAX_LOADSTRING 100 HINSTANCE hInst; TCHAR szTitle[MAX_LOADSTRING]; TCHAR szWindowClass[MAX_LOADSTRING]; // the callback functions for the dialogs LRESULT CALLBACK MainDlg(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK AboutDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK FreqDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK LengthDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK ProgressDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); enum FREQ_CALIB { FREQ_BINOMIAL, FREQ_POISSON, FREQ_EXACT, FREQ_MAX }; bool set[4] = {false, false, false, true}; char files[2048]; #define MAX_GENES 32 /**************************************************/ // this info is exported to the main program FREQ_CALIB freq = FREQ_BINOMIAL; int min_range = 6; int max_range = 8; char big_dtable_filename[MAX_PATH]; char small_dtable_filename[MAX_PATH]; char big_fasta_filename[MAX_PATH]; char small_fasta_filename[MAX_PATH]; char * gene_filenames[MAX_GENES]; int num_genefiles = 0; /**************************************************/ HWND progress; int total_progress = 0; // Author: Joseph Bertolami // Email: jbertola@uci.edu /* *FUNCTION: DWORD WINAPI ThreadProc(LPVOID lpParameter=0) *PURPOSE: Progressbar Threaded Procedure *REMARKS: */ DWORD WINAPI ThreadProc(LPVOID lpParameter=0) { // This was originally going to be placed in a separate thread, but eventually I pulled // it out of that setup because it was faster and more efficient this way, i.e. no need // for multi-threaded coordination objects etc. RECT mrect, prect; progress = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG4), MainWnd, (DLGPROC) ProgressDlg); GetWindowRect(MainWnd, &mrect); GetWindowRect(progress, &prect); MoveWindow(progress, mrect.left + (mrect.right - mrect.left)/2 - (prect.right - prect.left)/2, mrect.top + (mrect.bottom - mrect.top)/2 - (prect.bottom - prect.top)/2, prect.right - prect.left, prect.bottom - prect.top, TRUE); UpdateWindow(progress); ShowWindow(progress, SW_SHOWNORMAL); HWND ProgressBar = GetDlgItem(progress, IDC_PROGRESS1); SendMessage(ProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); SendMessage(ProgressBar, PBM_SETSTEP, (WPARAM) 1, 0); SendMessage(ProgressBar, PBM_SETPOS, (WPARAM) 0, 0); return 0; } // Author: Joseph Bertolami // Email: jbertola@uci.edu /* *FUNCTION: void ResetProgress() *PURPOSE: Resets progress bar *REMARKS: */ void ResetProgress() { // This function resets the progress bar total_progress = 0; HWND ProgressBar = GetDlgItem(progress, IDC_PROGRESS1); SendMessage(ProgressBar, PBM_SETPOS, (WPARAM) 0, 0); } // Author: Joseph Bertolami // Email: jbertola@uci.edu /* *FUNCTION: void SetProgress(int value) *PURPOSE: Sets progress bar *REMARKS: */ void SetProgress(int value) { // This function sets the progress bar total_progress = value; HWND ProgressBar = GetDlgItem(progress, IDC_PROGRESS1); SendMessage(ProgressBar, PBM_SETPOS, (WPARAM) value, 0); } // Author: Joseph Bertolami // Email: jbertola@uci.edu /* *FUNCTION: void IncrementProgress() *PURPOSE: increments progress bar by 1 *REMARKS: */ void IncrementProgress() { // This function increments the progress bar total_progress++; HWND ProgressBar = GetDlgItem(progress, IDC_PROGRESS1); SendMessage(ProgressBar, PBM_SETPOS, (WPARAM) total_progress, 0); } // Author: Joseph Bertolami // Email: jbertola@uci.edu // Edited by: Vishakh /* *FUNCTION: char *Process(...) *PURPOSE: Main process callback for primary computation *REMARKS: */ char *Process(char *big_dtable, char *small_dtable, int min_r, int max_r, int cfreq, char **genefiles, int num_gene_files) { // This is the main Process callback accessed from within the winproc // it is called when the user selects 'Process' from the UI menu. if ( !big_dtable || !small_dtable || !genefiles || num_gene_files == 0 ) return NULL; ThreadProc(); ResetProgress(); IncrementProgress(); DTable upstream_genome; DTable gene_family; IncrementProgress(); upstream_genome.loadFromFile(big_dtable); IncrementProgress(); gene_family.loadFromFile(small_dtable); if ( upstream_genome.getTotalSequences() <= 0 || gene_family.getTotalSequences() <= 0 ) MessageBox(NULL, "Upstream Genome or Gene Family is empty!", "Error on File Load", MB_ICONEXCLAMATION); SequenceFinder st; IncrementProgress(); st.assignScores(upstream_genome, gene_family); st.sortTable(); IncrementProgress(); vector tables; tables.resize(num_gene_files); vector > genes; for(int i=0; i temp = tables[i].flatten(); genes.push_back(temp); } st.createMatrices(genes); st.HTMLOutput(10, "output.html"); EnableWindow(MainWnd, TRUE); EndDialog(progress, 0); return "output.html"; //return NULL; } // Author: Joseph Bertolami // Email: jbertola@uci.edu /* *FUNCTION: void Convert(char *src_filename, char * dst_filename) *PURPOSE: Converts a fasta file to a dtable file *REMARKS: */ void Convert(char *src_filename, char * dst_filename) { if ( !src_filename || !dst_filename ) return; // load the fasta file, save as dtable DGFile srcFile; Permutation Permute; srcFile.ReadGeneFile(src_filename); Permute.permute(srcFile); Permute.dTable.writeToFile(dst_filename); } // Author: Joseph Bertolami // Email: jbertola@uci.edu /* *FUNCTION: void Win32_FillMainEdit(HWND hDlg, char *szFilename) *PURPOSE: Fills in main window's edit box with data *REMARKS: */ void Win32_FillMainEdit(HWND hDlg, char *szFilename) { // This function fills out the main edit box on the ui // with information about the files that are currently loaded // all this code is sub-optimal, first off, we could just // allocate 2*filesize upfront, and prevent double traversal // of data b/c either way you're allocating 2x, whether its // upfront at the start, or half way through the processing // while I hate to say 'its fast enough'... in this case, // 'its fast enough' FILE *f = fopen(szFilename, "r"); fseek(f, 0, SEEK_END); long length = ftell(f); fclose(f); char *data = new char[length]; f = fopen(szFilename, "r"); int index = 0; int num_newline = 0; while ( !feof(f) ) { char character = fgetc(f); if ( character == '\n' ) num_newline++; data[index++]= character; } char *newdata = new char[length+num_newline]; int j = 0; for ( int i = 0; i < length; i++ ) { if ( data[i] == '\n' ) { newdata[j++] = '\r'; newdata[j++] = data[i]; } else newdata[j++] = data[i]; } fclose(f); SetDlgItemText(hDlg, IDC_EDIT1, newdata); delete[] data; delete[] newdata; } // Author: Joseph Bertolami // Email: jbertola@uci.edu int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // This is the entry function, it sets up the main dialog // and any other housekeeping required InitCommonControls(); HACCEL hAccelTable; LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_GUISIMPLE, szWindowClass, MAX_LOADSTRING); INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwICC = ICC_LISTVIEW_CLASSES; InitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX); BOOL bRet = InitCommonControlsEx(&InitCtrls); memset(files, 0, 2048); hInst = hInstance; DialogBoxParam(hInst, (LPCSTR) IDD_DIALOG1, NULL, (DLGPROC) MainDlg, 0); hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_GUISIMPLE); for ( int i = 0; i < MAX_GENES; i++ ) if ( gene_filenames[i] ) free(gene_filenames[i]); return (int) 0; } // Author: Joseph Bertolami // Email: jbertola@uci.edu LRESULT CALLBACK MainDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { // The massive MainDlg, this handles all first level controls as well as // common control usage, general logic and flow design, error handling, and // data relay HWND hWnd = hDlg; MainWnd = hDlg; switch (message) { case WM_INITDIALOG: { //CheckDlgButton(hDlg, IDC_CHECK1, BST_CHECKED); return TRUE; } break; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_FILE_EXPORTFASTATODTABLE: { char source_fasta[MAX_PATH]; char dest_dtable[MAX_PATH]; memset(source_fasta, 0, MAX_PATH); memset(dest_dtable, 0, MAX_PATH); OPENFILENAME open; char szFilename[MAX_PATH]; memset(szFilename, 0, MAX_PATH); ZeroMemory(&open, sizeof(open)); open.lStructSize = sizeof(open); open.hwndOwner = hWnd; open.lpstrFilter = "Source Fasta File (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; open.lpstrFile = szFilename; open.nMaxFile = MAX_PATH; open.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; open.lpstrDefExt = "txt"; if(GetOpenFileName(&open)) { memcpy(source_fasta, szFilename, MAX_PATH); } else break; memset(szFilename, 0, MAX_PATH); ZeroMemory(&open, sizeof(open)); open.lStructSize = sizeof(open); open.hwndOwner = hWnd; open.lpstrFilter = "Destination DTable File (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; open.lpstrFile = szFilename; open.nMaxFile = MAX_PATH; open.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; open.lpstrDefExt = "txt"; if(GetSaveFileName(&open)) { memcpy(dest_dtable, szFilename, MAX_PATH); } else break; // convert here Convert(source_fasta, dest_dtable); } break; case ID_PROCESS_PROCESSDATA: { char error_str[512]; memset(error_str, 0, 512); strcat(error_str,"You must specify each the following to continue:\r\n\r\n"); if ( !set[0] ) strcat(error_str, "- Big DTable File (File->Open Big DTable File)\r\n\r\n"); if ( !set[1] ) strcat(error_str, "- Small DTable File (File->Open Small DTable File)\r\n\r\n"); if ( !set[2] ) strcat(error_str, "- At least one Gene File (File->Open Gene File)\r\n\r\n"); bool success = set[0] & set[1] & set[2] & set[3]; if (!success ) { MessageBox(hDlg, error_str, "Process Data", MB_ICONEXCLAMATION); break; } char * html_filename = strdup(Process(big_dtable_filename, small_dtable_filename, min_range, max_range, freq, gene_filenames, num_genefiles )); if ( html_filename != NULL ) { char buffer[MAX_PATH]; memset(buffer, 0, MAX_PATH); _getcwd(buffer, MAX_PATH); ShellExecute(hDlg, "open", html_filename, NULL, buffer, SW_SHOW); } } break; case ID_SETTINGS_SETCALIBRATION: { DialogBox(hInst, (LPCSTR) IDD_DIALOG2, hDlg, (DLGPROC) FreqDlg); } break; case ID_SETTINGS_SETTARGETGENELENGTH: { DialogBox(hInst, (LPCSTR) IDD_DIALOG3, hDlg, (DLGPROC) LengthDlg); } break; case IDCANCEL: case IDM_EXIT: { // if checkbox is enabled, we post a message! //if ( IsDlgButtonChecked(hDlg, IDC_CHECK1) == BST_CHECKED ) // MessageBox(NULL, "Checkbox is Checked!", "Success!", MB_OK); EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; case IDM_ABOUT: { DialogBox(hInst, (LPCSTR) IDD_ABOUTBOX, hDlg, (DLGPROC) AboutDlg); } break; case ID_FILE_CLOSE: { SetDlgItemText(hDlg, IDC_EDIT1, ""); SetWindowText( hDlg, "GeneGui v0.2a"); } break; case ID_FILE_OPENGENEFILE: { OPENFILENAME open; char szFilename[MAX_PATH]; memset(szFilename, 0, MAX_PATH); ZeroMemory(&open, sizeof(open)); open.lStructSize = sizeof(open); open.hwndOwner = hWnd; open.lpstrFilter = "Gene File (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; open.lpstrFile = szFilename; open.nMaxFile = MAX_PATH; open.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; open.lpstrDefExt = "txt"; if(GetOpenFileName(&open)) { if ( num_genefiles > MAX_GENES ) { MessageBox(hDlg, "Number of gene files specified exceeds maxinum allowable gene files", "Error on File Load", MB_ICONEXCLAMATION); break; } gene_filenames[num_genefiles++] = strdup(szFilename); char temp[200]; memset(temp,0,200); wsprintf(temp, "%s\r\n", szFilename); strcat(files, temp); SetDlgItemText(hDlg, IDC_EDIT1, files); set[2] = true; } } break; case ID_FILE_OPEN: { OPENFILENAME open; char szFilename[MAX_PATH]; memset(szFilename, 0, MAX_PATH); ZeroMemory(&open, sizeof(open)); open.lStructSize = sizeof(open); open.hwndOwner = hWnd; open.lpstrFilter = "Big DTable Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; open.lpstrFile = szFilename; open.nMaxFile = MAX_PATH; open.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; open.lpstrDefExt = "txt"; if(GetOpenFileName(&open)) { //Win32_FillMainEdit(hDlg, szFilename); // since this is the big dtable file.. we copy it over memset(big_dtable_filename, 0, MAX_PATH); memcpy(big_dtable_filename, szFilename, MAX_PATH); char temp[200]; memset(temp,0,200); wsprintf(temp, "%s\r\n", big_dtable_filename); strcat(files, temp); SetDlgItemText(hDlg, IDC_EDIT1, files); set[0] = true; } } break; case ID_FILE_OPENSMALLDTABLEFILE: { OPENFILENAME open; char szFilename[MAX_PATH]; memset(szFilename, 0, MAX_PATH); ZeroMemory(&open, sizeof(open)); open.lStructSize = sizeof(open); open.hwndOwner = hWnd; open.lpstrFilter = "Small DTable Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; open.lpstrFile = szFilename; open.nMaxFile = MAX_PATH; open.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; open.lpstrDefExt = "txt"; if(GetOpenFileName(&open)) { Win32_FillMainEdit(hDlg, szFilename); // since this is the big dtable file.. we copy it over memset(small_dtable_filename, 0, MAX_PATH); memcpy(small_dtable_filename, szFilename, MAX_PATH); char temp[200]; memset(temp,0,200); wsprintf(temp, "%s\r\n", small_dtable_filename); strcat(files, temp); SetDlgItemText(hDlg, IDC_EDIT1, files); set[1] = true; } } break; case ID_FILE_OPENBIGFASTAFILE: { OPENFILENAME open; char szFilename[MAX_PATH]; memset(szFilename, 0, MAX_PATH); ZeroMemory(&open, sizeof(open)); open.lStructSize = sizeof(open); open.hwndOwner = hWnd; open.lpstrFilter = "Big Fasta Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; open.lpstrFile = szFilename; open.nMaxFile = MAX_PATH; open.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; open.lpstrDefExt = "txt"; if(GetOpenFileName(&open)) { Win32_FillMainEdit(hDlg, szFilename); // since this is the big dtable file.. we copy it over memset(big_fasta_filename, 0, MAX_PATH); memcpy(big_fasta_filename, szFilename, MAX_PATH); char temp[200]; memset(temp,0,200); wsprintf(temp, "%s\r\n", big_fasta_filename); strcat(files, temp); SetDlgItemText(hDlg, IDC_EDIT1, files); set[2] = true; } } break; case ID_FILE_OPENSMALLFASTAFILE: { OPENFILENAME open; char szFilename[MAX_PATH]; memset(szFilename, 0, MAX_PATH); ZeroMemory(&open, sizeof(open)); open.lStructSize = sizeof(open); open.hwndOwner = hWnd; open.lpstrFilter = "Small Fasta Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; open.lpstrFile = szFilename; open.nMaxFile = MAX_PATH; open.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; open.lpstrDefExt = "txt"; if(GetOpenFileName(&open)) { Win32_FillMainEdit(hDlg, szFilename); // since this is the big dtable file.. we copy it over memset(small_fasta_filename, 0, MAX_PATH); memcpy(small_fasta_filename, szFilename, MAX_PATH); char temp[200]; memset(temp,0,200); wsprintf(temp, "%s\r\n", small_fasta_filename); strcat(files, temp); SetDlgItemText(hDlg, IDC_EDIT1, files); set[3] = true; } } break; case ID_FILE_CLOSEALL: { set[0] = set[1] = set[2] = false; memset(files, 0, 2048); SetDlgItemText(hDlg, IDC_EDIT1, ""); SetWindowText( hDlg, "GeneGui v0.2a"); } break; } break; } return FALSE; } // Author: Joseph Bertolami // Email: jbertola@uci.edu // About Box Callback LRESULT CALLBACK AboutDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: { EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } break; } return FALSE; } // Author: Joseph Bertolami // Email: jbertola@uci.edu // Progress Dialog Callback LRESULT CALLBACK ProgressDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: EnableWindow(MainWnd, FALSE); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: { EnableWindow(MainWnd, TRUE); EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } break; } return FALSE; } // Author: Joseph Bertolami // Email: jbertola@uci.edu // Frequency Dialog Callback LRESULT CALLBACK FreqDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { switch ( freq ) { case FREQ_BINOMIAL: CheckDlgButton(hDlg, IDC_RADIO1, BST_CHECKED); break; case FREQ_POISSON: CheckDlgButton(hDlg, IDC_RADIO2, BST_CHECKED); break; case FREQ_EXACT: CheckDlgButton(hDlg, IDC_RADIO3, BST_CHECKED); break; } return TRUE; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: { if ( IsDlgButtonChecked(hDlg, IDC_RADIO1) ) freq = FREQ_BINOMIAL; if ( IsDlgButtonChecked(hDlg, IDC_RADIO2) ) freq = FREQ_POISSON; if ( IsDlgButtonChecked(hDlg, IDC_RADIO3) ) freq = FREQ_EXACT; EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } break; } return FALSE; } // Author: Joseph Bertolami // Email: jbertola@uci.edu // Length Dialog Callback LRESULT CALLBACK LengthDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { char minr[80], maxr[80]; wsprintf(minr, "%i", min_range); wsprintf(maxr, "%i", max_range); SetDlgItemText(hDlg, IDC_EDIT1, minr); SetDlgItemText(hDlg, IDC_EDIT2, maxr); return TRUE; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: { char string1[80], string2[80]; GetDlgItemText(hDlg, IDC_EDIT1, string1, 80); GetDlgItemText(hDlg, IDC_EDIT2, string2, 80); min_range = atoi(string1); max_range = atoi(string2); EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } break; } return FALSE; }