Well, I'm not going to get really carried away here but it could look something like this: // GLOBAL DATA static PTCHAR gpBuf = NULL; int FindKey(LPCTSTR file, LPCTSTR key) { DWORD dwSize, dwRead; HANDLE hFile; // -1 return means can't open file. hFile = CreateFile(file, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if(hFile == INVALID_HANDLE_VALUE) return -1; // Filesize limited to < 4GB. // -2 return means can't allocate mem. dwSize = GetFileSize(hFile, NULL); gpBuf = malloc(dwSize); if(!gpBuf) {CloseHandle(hFile); return -2;} ReadFile(hFile, gpBuf, dwSize, &dwRead, NULL); CloseHandle(hFile); // Hand off to search function. iPos = FindMatch(key, dwRead); free(gpBuf); gpBuf = NULL; return iPos; } int FindMatch(LPCTSTR key, DWORD dwSize) { int key_len; PTCHAR p = gpBuf; key_len = lstrlen(key) - 1; for(p = gbBuf; p < gpBuf + dwSize; p++) { if(*p == *key) if(ConfirmMatch(p, key, key_len, 1)) return p - gpBuf; } return 0; } BOOL ConfirmMatch(PTCHAR p, LPCTSTR key, int key_len, int i) { if(i > key_len) return TRUE; if(*(p + i) == key[i]) return ConfirmMatch(p, key, ++i); return FALSE; } Note that all this does is return the byte position of the keyword. VEE can't directly use this information. It would still take more to return anything to VEE. Specifically, the rest of the array. That would take a pre-allocated VEE text array passed in. It's doable, but kind of silly.